python - 使用 Keras 的模型类将 Tensorflow 1.x 代码迁移到 Tensorflow 2.x
问题描述
我刚刚开始使用 Keras 2.3.1 和 Python 3.7.7 学习 Tensorflow 2.1.0。
我发现这个“使用原型网络的 Omniglot 字符集分类”github Jupyter Notebook,我认为它适用于 Tensorflow 1.x。
我的问题是这段代码:
for epoch in range(num_epochs):
for episode in range(num_episodes):
# select 60 classes
episodic_classes = np.random.permutation(no_of_classes)[:num_way]
support = np.zeros([num_way, num_shot, img_height, img_width], dtype=np.float32)
query = np.zeros([num_way, num_query, img_height, img_width], dtype=np.float32)
for index, class_ in enumerate(episodic_classes):
selected = np.random.permutation(num_examples)[:num_shot + num_query]
support[index] = train_dataset[class_, selected[:num_shot]]
# 5 querypoints per classs
query[index] = train_dataset[class_, selected[num_shot:]]
support = np.expand_dims(support, axis=-1)
query = np.expand_dims(query, axis=-1)
labels = np.tile(np.arange(num_way)[:, np.newaxis], (1, num_query)).astype(np.uint8)
_, loss_, accuracy_ = sess.run([train, loss, accuracy], feed_dict={support_set: support, query_set: query, y:labels})
if (episode+1) % 10 == 0:
print('Epoch {} : Episode {} : Loss: {}, Accuracy: {}'.format(epoch+1, episode+1, loss_, accuracy_))
是否有任何教程或书籍或文章可以帮助我使用 Keras 的模型将此代码迁移到 Tensorflow 2.x 和 Keras?
我想从链接中编写代码,如下所示:
import numpy as np
import os
import skimage.io as io
import skimage.transform as trans
import numpy as np
from keras.models import *
from keras.layers import *
from keras.optimizers import *
from keras.callbacks import ModelCheckpoint, LearningRateScheduler
from keras import backend as keras
def unet(pretrained_weights = None,input_size = (256,256,1)):
inputs = Input(input_size)
conv1 = Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(inputs)
conv1 = Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv1)
pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)
conv2 = Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool1)
conv2 = Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv2)
pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)
conv3 = Conv2D(256, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool2)
conv3 = Conv2D(256, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv3)
pool3 = MaxPooling2D(pool_size=(2, 2))(conv3)
conv4 = Conv2D(512, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool3)
conv4 = Conv2D(512, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv4)
drop4 = Dropout(0.5)(conv4)
pool4 = MaxPooling2D(pool_size=(2, 2))(drop4)
conv5 = Conv2D(1024, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool4)
conv5 = Conv2D(1024, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv5)
drop5 = Dropout(0.5)(conv5)
up6 = Conv2D(512, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(UpSampling2D(size = (2,2))(drop5))
merge6 = concatenate([drop4,up6], axis = 3)
conv6 = Conv2D(512, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(merge6)
conv6 = Conv2D(512, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv6)
up7 = Conv2D(256, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(UpSampling2D(size = (2,2))(conv6))
merge7 = concatenate([conv3,up7], axis = 3)
conv7 = Conv2D(256, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(merge7)
conv7 = Conv2D(256, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv7)
up8 = Conv2D(128, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(UpSampling2D(size = (2,2))(conv7))
merge8 = concatenate([conv2,up8], axis = 3)
conv8 = Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(merge8)
conv8 = Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv8)
up9 = Conv2D(64, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(UpSampling2D(size = (2,2))(conv8))
merge9 = concatenate([conv1,up9], axis = 3)
conv9 = Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(merge9)
conv9 = Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv9)
conv9 = Conv2D(2, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv9)
conv10 = Conv2D(1, 1, activation = 'sigmoid')(conv9)
model = Model(input = inputs, output = conv10)
model.compile(optimizer = Adam(lr = 1e-4), loss = 'binary_crossentropy', metrics = ['accuracy'])
#model.summary()
if(pretrained_weights):
model.load_weights(pretrained_weights)
return model
并在train.py
:
model = unet(...)
model.compile(...)
model.fit(...)
解决方案
Tensorflow dow有这个教程总结了所有内容。
最重要的是Sessions
它不再存在,模型应该使用tensorflow.keras.layers
.
现在,在训练模型时,您有 2 个选择,您可以使用 Keras 方式,也可以使用GradientTape
(有点旧的方式)。
这意味着您有两种选择,一种不会对您的代码产生太大影响(GradientTape),另一种只会让您改变一些事情(Keras)。
渐变胶带
GradientTape 用于您自己的循环并按照您的意愿计算梯度,它有点像 Tensorflow 1.X。
- 使用 Keras API 构建模型:
import tensorflow as tf
def unet(...):
inputs = tf.keras.layers.Input(shape_images)
...
model = Model(input = inputs, output = conv10)
model.compile(...)
return model
...
model = unet(...)
- 定义损失
mse = tf.keras.losses.MeanSquaredError()
- 定义优化器
optimizer = tf.keras.optimizer.Adam(lr=1e-4)
然后,您可以像往常一样进行培训,只是将旧的 Session 机制替换为 GradientTape :
for epoch in range(num_epochs):
for episode in range(num_episodes):
# select 60 classes
episodic_classes = np.random.permutation(no_of_classes)[:num_way]
support = np.zeros([num_way, num_shot, img_height, img_width], dtype=np.float32)
query = np.zeros([num_way, num_query, img_height, img_width], dtype=np.float32)
for index, class_ in enumerate(episodic_classes):
selected = np.random.permutation(num_examples)[:num_shot + num_query]
support[index] = train_dataset[class_, selected[:num_shot]]
# 5 querypoints per classs
query[index] = train_dataset[class_, selected[num_shot:]]
support = np.expand_dims(support, axis=-1)
query = np.expand_dims(query, axis=-1)
labels = np.tile(np.arange(num_way)[:, np.newaxis], (1, num_query)).astype(np.uint8)
# No session here but a Gradient computing
with tf.GradientTape() as tape:
prediction = model(support) # or whatever you need as input of model
loss = mse(label, prediction)
# apply gradient descent
grads = tape.gradient(loss, model.trainable_weights)
optimizer.apply_gradients(zip(grads, model.trainable_weights))
喀拉斯
对于 keras,您需要更改提供数据的方式,因为使用了 for 循环,您将不会有fit
,而您需要实现Generator或任何可以迭代的数据结构。这意味着您基本上需要一个(X, y)
. data_struct[0] 将为您提供第一个 X,Y 对。
一旦你有了这个数据结构,就很容易了。
像 GradientTape 一样定义模型
像 GradientTape 一样定义优化器
编译模型
model.compile(loss='binary_crossentropy', optimizer=optimizer, metrics=['accuracy']) # Or whatever you need as loss/metrics
- 使用您的 data_struct 拟合模型
model.fit(data_struct, epochs=500) # Add validation_data if you want, callback ...
推荐阅读
- c# - 使用外部令牌添加身份验证
- r - Data.table 在预期时产生两个值
- python - 使用不以冒号分隔的小时和分钟计算小时平均值
- c# - Blazor:如何开始随时间循环?示例 - 2 分钟后生成一个问题
- c# - 我如何将 AutoMapper 用于主细节类
- android - 如何将作为 CoordinatorLayout 的直接子级的组件约束到 ConstraintLayout 内的组件?
- php - CodeIgniter 3 - 动态加载客户端数据库
- strapi - 如何删除 Strapi 中的 ContentType 和相关的 db 表?
- ssl-certificate - 无法使用 Alamofire 5.0.2 应用证书固定
- apache-spark - Spark else() 总是被评估