gpt4 book ai didi

python - 如何在没有 ImageNet 权重的情况下进行迁移学习?

转载 作者:行者123 更新时间:2023-12-03 23:42:10 25 4
gpt4 key购买 nike

这是我的项目的描述:
数据集 1:更大的数据集,包含图像的二进制类。
数据集 2 : 包含 2在外观上与 Dataset1 非常相似的类.我想通过学习 Dataset1 来制作一个使用迁移学习的模型并在 Dataset2 中应用学习率较低的权重.
因此,我希望训练整个 VGG16dataset1 ,然后使用迁移学习微调 dataset2 的最后一层.我不想使用预训练的 imagenet 数据库。这是我正在使用的代码,我已经从中保存了 wights:


from tensorflow.keras.layers import Input, Lambda, Dense, Flatten
from tensorflow.keras.models import Model
from tensorflow.keras.applications.vgg16 import VGG16
from tensorflow.keras.applications.vgg16 import preprocess_input
from tensorflow.keras.preprocessing import image
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.models import Sequential
import numpy as np
from glob import glob
import matplotlib.pyplot as plt

vgg = VGG16(input_shape=(244, 244, 3), weights=None, include_top=False)

# don't train existing weights
for layer in vgg.layers:
layer.trainable = False

x = Flatten()(vgg.output)

import tensorflow.keras
prediction = tensorflow.keras.layers.Dense(2, activation='softmax')(x)

model = Model(inputs=vgg.input, outputs=prediction)

model.compile(
loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy']
)

from keras.preprocessing.image import ImageDataGenerator

train_datagen = ImageDataGenerator(rescale = 1./255,
shear_range = 0.2,
zoom_range = 0.2,
horizontal_flip = True)

test_datagen = ImageDataGenerator(rescale = 1./255)

training_set = train_datagen.flow_from_directory('chest_xray/train',
target_size = (224, 224),
batch_size = 32,
class_mode = 'categorical')

test_set = train_datagen.flow_from_directory('chest_xray/test',
target_size = (224, 224),
batch_size = 32,
class_mode = 'categorical')

# fit the model
r = model.fit_generator(
training_set,
validation_data=test_set,
epochs=5,
steps_per_epoch=len(training_set),
validation_steps=len(test_set)
)

model.save_weights('first_try.h5')

最佳答案

更新
根据您的查询,似乎 中的类(class)编号不会有所不同。数据集 2 .同时,您也不想使用图像净重。因此,在这种情况下,您不需要映射或存储权重(如下所述)。只需加载模型和重量并在 上训练数据集 2 .卡住来自 的所有训练层数据集 1 并在 上训练最后一层数据集 2 ;真的很直接。

In my below response, though you're not needed the full information, I am keeping that anyway for future reference.



这是您可能需要的一个小演示。希望它能给你一些见解。在这里我们将训练 CIRFAR具有 10 的数据集类并尝试将其用于不同数据集的迁移学习,这些数据集可能具有不同的输入大小和不同的类数。
准备 CIFAR(10 节课)
import numpy as np
import tensorflow as tf
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D, Dropout

(x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()

# train set / data
x_train = x_train.astype('float32') / 255

# validation set / data
x_test = x_test.astype('float32') / 255

# train set / target
y_train = tf.keras.utils.to_categorical(y_train, num_classes=10)
# validation set / target
y_test = tf.keras.utils.to_categorical(y_test, num_classes=10)

print(x_train.shape, y_train.shape)
print(x_test.shape, y_test.shape)
'''
(50000, 32, 32, 3) (50000, 10)
(10000, 32, 32, 3) (10000, 10)
'''
模型
# declare input shape 
input = tf.keras.Input(shape=(32,32,3))
# Block 1
x = tf.keras.layers.Conv2D(32, 3, strides=2, activation="relu")(input)
x = tf.keras.layers.MaxPooling2D(3)(x)

# Now that we apply global max pooling.
gap = tf.keras.layers.GlobalMaxPooling2D()(x)

# Finally, we add a classification layer.
output = tf.keras.layers.Dense(10, activation='softmax')(gap)

# bind all
func_model = tf.keras.Model(input, output)

'''
Model: "functional_3"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_2 (InputLayer) [(None, 32, 32, 3)] 0
_________________________________________________________________
conv2d_1 (Conv2D) (None, 15, 15, 32) 896
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 5, 5, 32) 0
_________________________________________________________________
global_max_pooling2d_1 (Glob (None, 32) 0
_________________________________________________________________
dense_1 (Dense) (None, 10) 330
=================================================================
Total params: 1,226
Trainable params: 1,226
Non-trainable params: 0
'''
运行模型以获得一些权重矩阵,如下所示:
# compile 
print('\nFunctional API')
func_model.compile(
loss = tf.keras.losses.CategoricalCrossentropy(),
metrics = tf.keras.metrics.CategoricalAccuracy(),
optimizer = tf.keras.optimizers.Adam())
# fit
func_model.fit(x_train, y_train, batch_size=128, epochs=1)
迁移学习
让我们用它来 MNIST .它还有 10类,但为了需要不同数量的类,我们将制作 evenodd来自它的类别( 2 类)。下面我们将如何准备这些数据集
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()

# train set / data
x_train = np.expand_dims(x_train, axis=-1)
x_train = np.repeat(x_train, 3, axis=-1)
x_train = x_train.astype('float32') / 255
# train set / target
y_train = tf.keras.utils.to_categorical((y_train % 2 == 0).astype(int),
num_classes=2)

# validation set / data
x_test = np.expand_dims(x_test, axis=-1)
x_test = np.repeat(x_test, 3, axis=-1)
x_test = x_test.astype('float32') / 255
# validation set / target

y_test = tf.keras.utils.to_categorical((y_test % 2 == 0).astype(int),
num_classes=2)

print(x_train.shape, y_train.shape)
print(x_test.shape, y_test.shape)
'''
(60000, 28, 28, 3) (60000, 2)
(10000, 28, 28, 3) (10000, 2)
'''
如果您熟悉 keras 中 ImageNet 预训练权重的用法模型,你可能使用 include_top .通过设置它 False我们可以轻松加载一个没有预训练模型顶级信息的权重文件。所以在这里我们需要手动(有点)做到这一点。我们需要获取权重矩阵直到最后一个激活层(在我们的例子中是 Dense(10, softmax))。并将其放入基础模型的新实例中,然后 + 我们添加一个新的分类器层(在我们的示例中为 Dense(2, softmax)
for i, layer in enumerate(func_model.layers):
print(i,'\t',layer.trainable,'\t :',layer.name)

'''
Train_Bool : Layer Names
0 True : input_1
1 True : conv2d
2 True : max_pooling2d
3 True : global_max_pooling2d # < we go till here to grab the weight and biases
4 True : dense # 10 classes (from previous model)
'''
获取权重
sparsified_weights = []
for w in func_model.get_layer(name='global_max_pooling2d').get_weights():
sparsified_weights.append(w)
通过这个,我们从旧模型映射权重,除了分类器层( Dense )。请注意,这里我们抓取重量直到 GAP层,它就在分类器之前。
现在,我们将创建一个新模型,除了最后一层( 10 Dense )与旧模型相同,同时添加一个新的 Dense2单元。
predictions    = Dense(2, activation='softmax')(func_model.layers[-2].output)
new_func_model = Model(inputs=func_model.inputs, outputs = predictions)
现在我们可以为新模型设置如下权重:
new_func_model.get_layer(name='global_max_pooling2d').set_weights(sparsified_weights)
您可以通过以下方式检查验证;除了最后一层之外,一切都将相同。
func_model.get_weights()      # last layer, Dense (10)
new_func_model.get_weights() # last layer, Dense (2)
现在您可以使用新数据集训练模型,在我们的例子中是 MNIST
new_func_model.compile(optimizer='adam', loss='categorical_crossentropy')
new_func_model.summary()

'''
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) [(None, 32, 32, 3)] 0
_________________________________________________________________
conv2d (Conv2D) (None, 15, 15, 32) 896
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 5, 5, 32) 0
_________________________________________________________________
global_max_pooling2d (Global (None, 32) 0
_________________________________________________________________
dense_6 (Dense) (None, 2) 66
=================================================================
Total params: 962
Trainable params: 962
Non-trainable params: 0
'''

# compile
print('\nFunctional API')
new_func_model.compile(
loss = tf.keras.losses.CategoricalCrossentropy(),
metrics = tf.keras.metrics.CategoricalAccuracy(),
optimizer = tf.keras.optimizers.Adam())
# fit
new_func_model.fit(x_train, y_train, batch_size=128, epochs=1)
WARNING:tensorflow:Model was constructed with shape (None, 32, 32, 3) for input Tensor("input_1:0", shape=(None, 32, 32, 3), dtype=float32), but it was called on an input with incompatible shape (None, 28, 28, 3).
WARNING:tensorflow:Model was constructed with shape (None, 32, 32, 3) for input Tensor("input_1:0", shape=(None, 32, 32, 3), dtype=float32), but it was called on an input with incompatible shape (None, 28, 28, 3).
469/469 [==============================] - 1s 3ms/step - loss: 0.6453 - categorical_accuracy: 0.6447
<tensorflow.python.keras.callbacks.History at 0x7f7af016feb8>

关于python - 如何在没有 ImageNet 权重的情况下进行迁移学习?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65136547/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com