经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 大数据/云/AI » 人工智能基础 » 查看文章
【tf.keras】tf.keras加载AlexNet预训练模型
来源:cnblogs  作者:wuliytTaotao  时间:2019/5/30 8:44:36  对本文有异议

tf.keras 的预训练模型都放在了'tensorflow.python.keras.applications' 目录下,在 tensorflow 1.10 版本中,预训练好的模型有:

DenseNet121, DenseNet169, DenseNet201, InceptionResNetV2, InceptionV3, MobileNet, NASNetLarge, NASNetMobile, ResNet50, VGG16, VGG19, Xception.

找了半天,发现 keras 没有预训练好的 AlexNet。。。

所以本文提供一种从其它框架(如 PyTorch)导入预训练模型的方法,下面以 AlexNet 为例。

从 PyTorch 中导出模型参数

首先明白一点,当模型的结构一样时,我们只需要导入模型的参数即可复现模型,所以我们要做的就是从 PyTorch 中导出预训练好的模型参数,并用 keras 加载。

这里要介绍一个微软的项目:MMdnn。MMdnn 使我们可以在不同深度学习框架之间转换模型,这里我也使用 MMdnn 来转换 AlexNet(PyTorch to Keras)。

第 0 步:配置环境

  1. 必须一致配置:
  2. - PyTorch: 0.4.0 (如果其它版本出现了问题,请退回到 0.4.0 版)
  3. 非必须一致配置:
  4. - numpy: 1.14.5

第 1 步:安装 MMdnn

  1. $ pip3 install mmdnn

其它安装方式请参考 github

第 2 步:得到 PyTorch 保存完整结构和参数的模型(pth 文件)

PyTorch 保存模型时,可以保存整个模型,也可以仅保存模型的参数,都是存放到 pth 文件中。

mmdnn 操作的 pth 文件是要求含有模型结构的,具体参见 FAQ,而在 PyTorch 中预训练 AlexNet 仅保存了参数。

通过以下程序得到包含有模型结构和权重的 AlexNet 预训练模型(pth 文件):

  1. import torchvision
  2. m = torchvision.models.alexnet(pretrained=True)
  3. torch.save(m, './alexnet.pth')

对于其它模型,如 resnet101,可以通过以下指令直接得到含有结构和权重的预训练模型:

  1. $ mmdownload -f pytorch -n resnet101 -o ./

(不要通过上述指令得到 alexnet.pth,因为其仅仅包含权重,而不含结构,故后面一步会出现错误 "AttributeError: 'collections.OrderedDict' object has no attribute 'state_dict'"。)

第 3 步:导出 PyTorch 模型的参数,保存至 hdf5 文件

依次执行以下三条指令,最后会得到一个 'keras_alexnet.h5' 文件,这就是我们想要的 keras 能加载的预训练权重文件。

  1. $ mmtoir -f pytorch -d alexnet --inputShape 3,227,227 -n alexnet.pth
  2. IR network structure is saved as [alexnet.json].
  3. IR network structure is saved as [alexnet.pb].
  4. IR weights are saved as [alexnet.npy].
  5. $ mmtocode -f keras --IRModelPath alexnet.pb --IRWeightPath alexnet.npy --dstModelPath keras_alexnet.py
  6. Using TensorFlow backend.
  7. Parse file [alexnet.pb] with binary format successfully.
  8. Target network code snippet is saved as [keras_alexnet.py].
  9. $ python3 -m mmdnn.conversion.examples.keras.imagenet_test -n keras_alexnet.py -w alexnet.npy --dump keras_alexnet.h5
  10. Using TensorFlow backend.
  11. Keras model file is saved as [keras_alexnet.h5], generated by [keras_alexnet.py.py] and [alexnet.npy].

可能遇到的问题

  • AttributeError: 'Conv2d' object has no attribute 'padding_mode'

Solution:PyTorch 版本问题,1.1.0 版会出现这个问题,回退到 0.4.0 版本即可。

  1. $ pip install -i https://pypi.tuna.tsinghua.edu.cn/simple --upgrade torch==0.4.0 torchvision==0.2.0

Solution:请更改 numpy 版本。

Solution:pth 文件仅含模型参数而不含模型结构,在 PyTorch 中加载一下然后保存含有模型结构和参数的 pth 文件。

验证从 PyTorch 导出的 AlexNet 预训练模型

测试用的几张图片、代码以及生成的 keras_alexnet.h5 文件都存放到了云盘:(链接:https://pan.baidu.com/s/1TCbSHn5DC7pPIk-0dnbmgg 密码:8njp)。

  1. import torch
  2. import torchvision
  3. import cv2
  4. import numpy as np
  5. from torch.autograd import Variable
  6. import tensorflow as tf
  7. from tensorflow.keras import layers,regularizers
  8. filename_test = 'data/dog2.png'
  9. img = cv2.imread(filename_test)
  10. img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
  11. # 数据预处理
  12. img = cv2.resize(img, (227, 227))
  13. img = img / 255.0
  14. img = np.reshape(img, (1, 227, 227, 3))
  15. # 标准化,这是 PyTorch 预训练 AlexNet 模型的预处理方式,详情请见 https://pytorch.org/docs/stable/torchvision/models.html
  16. mean = np.array([0.485, 0.456, 0.406]).reshape([1, 1, 1, 3])
  17. std = np.array([0.229, 0.224, 0.225]).reshape([1, 1, 1, 3])
  18. img = (img - mean) / std
  19. # PyTorch
  20. # PyTorch 数据输入 channel 排列和 Keras 不一致
  21. img_tmp = np.transpose(img, (0, 3, 1, 2))
  22. model = torchvision.models.alexnet(pretrained=True)
  23. # torch.save(model, './model/alexnet.pth')
  24. model = model.double()
  25. model.eval()
  26. y = model(Variable(torch.tensor(img_tmp)))
  27. # 预测的类别
  28. print(np.argmax(y.detach().numpy()))
  29. # Keras
  30. def get_AlexNet(num_classes=1000, drop_rate=0.5, regularizer_rate=0.01):
  31. """
  32. PyTorch 中实现的 AlexNet 预训练模型结构,filter 的深度分别为:(64,192,384,256,256)。
  33. 返回 AlexNet 的 inputs 和 outputs
  34. """
  35. inputs = layers.Input(shape=[227, 227, 3])
  36. conv1 = layers.Conv2D(64, (11, 11), strides=(4, 4), padding='valid', activation='relu')(inputs)
  37. pool1 = layers.MaxPooling2D(pool_size=(3, 3), strides=(2, 2))(conv1)
  38. conv2 = layers.Conv2D(192, (5, 5), strides=(1, 1), padding='same', activation='relu')(pool1)
  39. pool2 = layers.MaxPooling2D(pool_size=(3, 3), strides=(2, 2))(conv2)
  40. conv3 = layers.Conv2D(384, (3, 3), strides=(1, 1), padding='same', activation='relu')(pool2)
  41. conv4 = layers.Conv2D(256, (3, 3), strides=(1, 1), padding='same', activation='relu')(conv3)
  42. conv5 = layers.Conv2D(256, (3, 3), strides=(1, 1), padding='same', activation='relu')(conv4)
  43. pool3 = layers.MaxPooling2D(pool_size=(3, 3), strides=(2, 2))(conv5)
  44. flat = layers.Flatten()(pool3)
  45. dense1 = layers.Dense(4096, activation='relu', kernel_regularizer=regularizers.l2(regularizer_rate))(flat)
  46. dense1 = layers.Dropout(drop_rate)(dense1)
  47. dense2 = layers.Dense(4096, activation='relu', kernel_regularizer=regularizers.l2(regularizer_rate))(dense1)
  48. dense2 = layers.Dropout(drop_rate)(dense2)
  49. outputs = layers.Dense(num_classes, activation='softmax', kernel_regularizer=regularizers.l2(regularizer_rate))(dense2)
  50. return inputs, outputs
  51. inputs, outputs = get_AlexNet()
  52. model2 = tf.keras.Model(inputs, outputs)
  53. model2.load_weights('./keras_alexnet.h5')
  54. # 预测的类别
  55. print(np.argmax(model2.predict(img)))

预测结果代表的类别请看博客 ImageNet图像库1000个类别名称(中文注释不断更新)

Attentions

PyTorch 中的预训练 AlexNet 模型卷积层 filter 的个数和原论文不一致,filter 的个数分别 \(64,192,384,256,256\)。具体参见 GitHub - pytorch: vision/torchvision/models/alexnet.py

PyTorch 给出的解释是,它的预训练 AlexNet 模型用的是论文 Krizhevsky, A. (2014). One weird trick for parallelizing convolutional neural networks. arXiv preprint arXiv:1404.5997. 给出的架构,但 PyTorch 的模型架构和这篇论文还是有区别,这篇论文中第四个卷积层 filter 个数为 384,而 PyTorch 为 256。

而 caffe 中实现的 AlexNet 含有原始的 LRN 层,去掉 LRN 层后,个人感觉预训练的权重就不能直接拿来用了。

References

GitHub - microsoft/MMdnn
ImageNet图像库1000个类别名称(中文注释不断更新)-- 徐小妹

原文链接:http://www.cnblogs.com/wuliytTaotao/p/10942877.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号