简体   繁体   English

使用 Keras 的 model ZA2F2ED4F298E054E4FB8821C5ED2Z 2.x 将 Tensorflow 1.x 代码迁移到 Tensorflow 2.x

[英]Migrate Tensorflow 1.x code to Tensorflow 2.x using Keras' model class

I've just started to learn Tensorflow 2.1.0 with Keras 2.3.1 and Python 3.7.7.我刚刚开始学习 Tensorflow 2.1.0 和 Keras 2.3.1 和 Python 3.7.7。

I have found this " Omniglot Character Set Classification Using Prototypical Network " github Jupyter Notebook, that I think it works with Tensorflow 1.x.我发现这个“ 使用原型网络的 Omniglot 字符集分类” github Jupyter Notebook,我认为它适用于 Tensorflow 1.x。

My problem is with this piece of code:我的问题是这段代码:

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_))

Is there any tutorial or book or article to help me to migrate this code to Tensorflow 2.x and Keras, using Keras' model?是否有任何教程或书籍或文章可以帮助我使用 Keras 的 model 将此代码迁移到 Tensorflow 2.x 和 Keras?

I want to write the code from the link about like this one:我想从链接中编写代码,如下所示:

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

and in train.py :train.py中:

model = unet(...)
model.compile(...)
model.fit(...)

There is this tutorial from Tensorflow dow that sums everything up. Tensorflow 的这篇教程总结了一切。

The most important things is that Sessions doesn't exist anymore, and model should be created using tensorflow.keras.layers .最重要的是Sessions不存在了,model 应该使用tensorflow.keras.layers创建。

Now when training a model you have 2 choices, either you use the Keras way or you can use the GradientTape (which is kinda the old way).现在,在训练 model 时,您有 2 个选择,您可以使用 Keras 方式,也可以使用GradientTape (这有点旧方式)。

That means you have two choices, one that won't make much difference in your code (GradientTape), one that will make you change few things(Keras).这意味着您有两种选择,一种不会对您的代码产生太大影响(GradientTape),另一种只会让您改变一些事情(Keras)。

Gradient Tape渐变胶带

GradientTape is used when you want to do your own loop and compute the gradient like you want, it's kinda like Tensorflow 1.X. GradientTape 用于您想要自己循环并计算所需的渐变,它有点像 Tensorflow 1.X。

  • Build your model using Keras API:使用 Keras API 构建您的 model:
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(...)
  • Define loss定义损失
mse = tf.keras.losses.MeanSquaredError()
  • Define optimizer定义优化器
optimizer = tf.keras.optimizer.Adam(lr=1e-4)

Then, you do the training as you would usually do, except that you replace the old Session mechanism by GradientTape:然后,您像往常一样进行训练,只是将旧的 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 Keras

For keras you need to change your way of feeding the data, you won't have a for loop since you use fit , whereas you need to implement a Generator or whatever data structure that can be iterated through.对于 keras,您需要更改提供数据的方式,因为使用fit ,您将没有 for 循环,而您需要实现Generator或任何可以迭代的数据结构。 That means that you basically need a list of (X, y) .这意味着您基本上需要(X, y)的列表。 data_struct[0] will give you the first X,Y pair. data_struct[0] 将为您提供第一个 X,Y 对。

Once you have this data structure it's easy.一旦你有了这个数据结构,就很容易了。

  • Define the model just like GradientTape像 GradientTape 一样定义 model

  • Define optimizer just like GradientTape像 GradientTape 一样定义优化器

  • Compile the model编译 model


model.compile(loss='binary_crossentropy', optimizer=optimizer, metrics=['accuracy']) # Or whatever you need as loss/metrics

  • Fit the model using your data_struct使用您的 data_struct 安装 model
model.fit(data_struct, epochs=500) # Add validation_data if you want, callback ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM