如何运用迁移学习 迁移学习涉及到使用一个在相关任务上训练过的模型的全部或部分。
Keras提供了一系列预先训练的模型,可以通过Keras应用程序API全部或部分地加载和使用这些模型。 一个有用的迁移学习模型是VGG模型之一,例如VGG-16,它有16层,在开发时在ImageNet照片分类挑战中取得了最好的成绩。 该模型由两个主要部分组成:模型的特征提取器部分由VGG块组成,模型的分类器部分由全连通层层和输出层组成。
我们可以使用模型的特征提取部分,并在模型中添加一个新的分类器部分,该分类器部分是针对行星数据集量身定制的。具体来说,我们可以在训练中保持所有卷积层的权重不变,只训练新的全连通层,这些全连通层将学习如何解释从模型中提取的特征,并进行一套二进制分类。
这可以通过加载VGG-16模型,从模型的输出端移除全连接层,然后添加新的全连接层来解释模型输出并做出预测来实现。通过将“include_top”参数设置为“False”,可以自动删除模型的分类器部分,这也要求为模型指定输入的形状,在本例中为(128,128,3)。这意味着加载的模型在最后一个最大池化层结束,之后我们可以手动添加Flatten图层和新分类器完全连接的图层。
下面的define_model()函数实现了这一点,并返回一个准备好进行培训的新模型。
代码语言:javascript复制 1# define cnn model
2def define_model(in_shape=(128, 128, 3), out_shape=17):
3 # load model
4 model = VGG16(include_top=False, input_shape=in_shape)
5 # mark loaded layers as not trainable
6 for layer in model.layers:
7 layer.trainable = False
8 # add new classifier layers
9 flat1 = Flatten()(model.layers[-1].output)
10 class1 = Dense(128, activation='relu', kernel_initializer='he_uniform')(flat1)
11 output = Dense(out_shape, activation='sigmoid')(class1)
12 # define new model
13 model = Model(inputs=model.inputs, outputs=output)
14 # compile model
15 opt = SGD(lr=0.01, momentum=0.9)
16 model.compile(optimizer=opt, loss='binary_crossentropy', metrics=[fbeta])
17 return model
一旦创建,我们就可以像以前一样在训练数据集中训练模型。
在这种情况下,不需要进行大量的训练,因为只有新的完全连接和输出层具有可训练的权重。因此,我们将训练时期的数量固定为10。
VGG16模型在特定的ImageNet挑战数据集上进行了训练。因此,模型期望图像居中。也就是说,从输入中减去ImageNet训练数据集上计算的每个通道(红色,绿色和蓝色)的平均像素值。
Keras提供了通过preprocess_input()函数为单个照片执行此准备的功能。尽管如此,我们可以通过将“ featurewise_center ”参数设置为“ True ”并手动指定在以ImageNet训练数据集为中心时使用的平均像素值来实现与图像数据生成器相同的效果:[123.68,116.779 ,103.939]。
代码语言:javascript复制1# create data generator
2datagen = ImageDataGenerator(featurewise_center=True)
3# specify imagenet mean values for centering
4datagen.mean = [123.68, 116.779, 103.939]
5 return model
下面列出了用于行星数据集上的转移学习的VGG-16模型的完整代码清单。
代码语言:javascript复制 1# vgg16 transfer learning on the planet dataset
2import sys
3from numpy import load
4from matplotlib import pyplot
5from sklearn.model_selection import train_test_split
6from keras import backend
7from keras.layers import Dense
8from keras.layers import Flatten
9from keras.optimizers import SGD
10from keras.applications.vgg16 import VGG16
11from keras.models import Model
12from keras.preprocessing.image import ImageDataGenerator
13
14# load train and test dataset
15def load_dataset():
16 # load dataset
17 data = load('planet_data.npz')
18 X, y = data['arr_0'], data['arr_1']
19 # separate into train and test datasets
20 trainX, testX, trainY, testY = train_test_split(X, y, test_size=0.3, random_state=1)
21 print(trainX.shape, trainY.shape, testX.shape, testY.shape)
22 return trainX, trainY, testX, testY
23
24# calculate fbeta score for multi-class/label classification
25def fbeta(y_true, y_pred, beta=2):
26 # clip predictions
27 y_pred = backend.clip(y_pred, 0, 1)
28 # calculate elements
29 tp = backend.sum(backend.round(backend.clip(y_true * y_pred, 0, 1)), axis=1)
30 fp = backend.sum(backend.round(backend.clip(y_pred - y_true, 0, 1)), axis=1)
31 fn = backend.sum(backend.round(backend.clip(y_true - y_pred, 0, 1)), axis=1)
32 # calculate precision
33 p = tp / (tp fp backend.epsilon())
34 # calculate recall
35 r = tp / (tp fn backend.epsilon())
36 # calculate fbeta, averaged across each class
37 bb = beta ** 2
38 fbeta_score = backend.mean((1 bb) * (p * r) / (bb * p r backend.epsilon()))
39 return fbeta_score
40
41# define cnn model
42def define_model(in_shape=(128, 128, 3), out_shape=17):
43 # load model
44 model = VGG16(include_top=False, input_shape=in_shape)
45 # mark loaded layers as not trainable
46 for layer in model.layers:
47 layer.trainable = False
48 # add new classifier layers
49 flat1 = Flatten()(model.layers[-1].output)
50 class1 = Dense(128, activation='relu', kernel_initializer='he_uniform')(flat1)
51 output = Dense(out_shape, activation='sigmoid')(class1)
52 # define new model
53 model = Model(inputs=model.inputs, outputs=output)
54 # compile model
55 opt = SGD(lr=0.01, momentum=0.9)
56 model.compile(optimizer=opt, loss='binary_crossentropy', metrics=[fbeta])
57 return model
58
59# plot diagnostic learning curves
60def summarize_diagnostics(history):
61 # plot loss
62 pyplot.subplot(211)
63 pyplot.title('Cross Entropy Loss')
64 pyplot.plot(history.history['loss'], color='blue', label='train')
65 pyplot.plot(history.history['val_loss'], color='orange', label='test')
66 # plot accuracy
67 pyplot.subplot(212)
68 pyplot.title('Fbeta')
69 pyplot.plot(history.history['fbeta'], color='blue', label='train')
70 pyplot.plot(history.history['val_fbeta'], color='orange', label='test')
71 # save plot to file
72 filename = sys.argv[0].split('/')[-1]
73 pyplot.savefig(filename '_plot.png')
74 pyplot.close()
75
76# run the test harness for evaluating a model
77def run_test_harness():
78 # load dataset
79 trainX, trainY, testX, testY = load_dataset()
80 # create data generator
81 datagen = ImageDataGenerator(featurewise_center=True)
82 # specify imagenet mean values for centering
83 datagen.mean = [123.68, 116.779, 103.939]
84 # prepare iterators
85 train_it = datagen.flow(trainX, trainY, batch_size=128)
86 test_it = datagen.flow(testX, testY, batch_size=128)
87 # define model
88 model = define_model()
89 # fit model
90 history = model.fit_generator(train_it, steps_per_epoch=len(train_it),
91 validation_data=test_it, validation_steps=len(test_it), epochs=20, verbose=0)
92 # evaluate model
93 loss, fbeta = model.evaluate_generator(test_it, steps=len(test_it), verbose=0)
94 print('> loss=%.3f, fbeta=%.3f' % (loss, fbeta))
95 # learning curves
96 summarize_diagnostics(history)
97
98# entry point, run the test harness
99run_test_harness()
首先运行示例适合模型,然后在保持测试数据集上报告模型性能。 鉴于学习算法的随机性,您的具体结果可能会有所不同。 在这种情况下,我们可以看到模型的F-beta得分约为0.860,优于基准模型,但不如图像数据增加的基模准型好。
回顾学习曲线,我们可以看到该模型对数据集的拟合速度很快,仅在几个训练阶段就显示出很强的过拟合。 结果表明,该模型可以通过正则化来解决过度拟合问题,或者通过模型的其他变化或学习过程来减缓改进的速度。
VGG-16模型的设计目的是将物体的照片分为1000个类别之一。因此,它被设计用来挑选对象的细粒度特性。我们可以猜测,更深层次的模型学习到的特征将代表ImageNet数据集中看到的更高阶的特征,这些特征可能与亚马逊雨林卫星照片的分类没有直接关系。 为了解决这个问题,我们可以重新拟合VGG-16模型,并允许训练算法对模型中某些层的权重进行微调。在本例中,我们将使三个卷积层(以及一致性池化层)成为可训练的。下面列出了define_model()函数的更新版本。
代码语言:javascript复制 1# define cnn model
2def define_model(in_shape=(128, 128, 3), out_shape=17):
3 # load model
4 model = VGG16(include_top=False, input_shape=in_shape)
5 # mark loaded layers as not trainable
6 for layer in model.layers:
7 layer.trainable = False
8 # allow last vgg block to be trainable
9 model.get_layer('block5_conv1').trainable = True
10 model.get_layer('block5_conv2').trainable = True
11 model.get_layer('block5_conv3').trainable = True
12 model.get_layer('block5_pool').trainable = True
13 # add new classifier layers
14 flat1 = Flatten()(model.layers[-1].output)
15 class1 = Dense(128, activation='relu', kernel_initializer='he_uniform')(flat1)
16 output = Dense(out_shape, activation='sigmoid')(class1)
17 # define new model
18 model = Model(inputs=model.inputs, outputs=output)
19 # compile model
20 opt = SGD(lr=0.01, momentum=0.9)
21 model.compile(optimizer=opt, loss='binary_crossentropy', metrics=[fbeta])
然后可以使用此修改重新运行在行星数据集上使用VGG-16进行传递学习的示例。 鉴于学习算法的随机性,您的具体结果可能会有所不同。 在这种情况下,与VGG-16模型特征提取模型相比,我们看到模型性能有所提升,因为正在将F-β评分从大约0.860提高到大约0.879。该分数接近于基准模型所见的F-beta分数,并增加了图像数据增强。
回顾学习曲线,我们可以看到模型在运行中相对早期仍显示过度拟合训练数据集的迹象。结果表明,该模型可能会受益于使用dropout和/或其他正规化方法。
鉴于我们在基准模型上使用数据增强看到了很大的改进,看看数据增强是否可用于通过微调来改善VGG-16模型的性能可能会很有趣。 在本例中,可以使用相同的define_model()函数,但在本例中,可以像上一节中执行的那样,更新run_test_harness(),以使用图像数据增强。我们期望增加的数据会减慢改进的速度。因此,我们将把训练周期从20个增加到50个,以给模型更多的时间来收敛。 下面列出了带有微调和数据增强功能的完整VGG-16示例。
代码语言:javascript复制 1# vgg with fine-tuning and data augmentation for the planet dataset
2import sys
3from numpy import load
4from matplotlib import pyplot
5from sklearn.model_selection import train_test_split
6from keras import backend
7from keras.layers import Dense
8from keras.layers import Flatten
9from keras.optimizers import SGD
10from keras.applications.vgg16 import VGG16
11from keras.models import Model
12from keras.preprocessing.image import ImageDataGenerator
13
14# load train and test dataset
15def load_dataset():
16 # load dataset
17 data = load('planet_data.npz')
18 X, y = data['arr_0'], data['arr_1']
19 # separate into train and test datasets
20 trainX, testX, trainY, testY = train_test_split(X, y, test_size=0.3, random_state=1)
21 print(trainX.shape, trainY.shape, testX.shape, testY.shape)
22 return trainX, trainY, testX, testY
23
24# calculate fbeta score for multi-class/label classification
25def fbeta(y_true, y_pred, beta=2):
26 # clip predictions
27 y_pred = backend.clip(y_pred, 0, 1)
28 # calculate elements
29 tp = backend.sum(backend.round(backend.clip(y_true * y_pred, 0, 1)), axis=1)
30 fp = backend.sum(backend.round(backend.clip(y_pred - y_true, 0, 1)), axis=1)
31 fn = backend.sum(backend.round(backend.clip(y_true - y_pred, 0, 1)), axis=1)
32 # calculate precision
33 p = tp / (tp fp backend.epsilon())
34 # calculate recall
35 r = tp / (tp fn backend.epsilon())
36 # calculate fbeta, averaged across each class
37 bb = beta ** 2
38 fbeta_score = backend.mean((1 bb) * (p * r) / (bb * p r backend.epsilon()))
39 return fbeta_score
40
41# define cnn model
42def define_model(in_shape=(128, 128, 3), out_shape=17):
43 # load model
44 model = VGG16(include_top=False, input_shape=in_shape)
45 # mark loaded layers as not trainable
46 for layer in model.layers:
47 layer.trainable = False
48 # allow last vgg block to be trainable
49 model.get_layer('block5_conv1').trainable = True
50 model.get_layer('block5_conv2').trainable = True
51 model.get_layer('block5_conv3').trainable = True
52 model.get_layer('block5_pool').trainable = True
53 # add new classifier layers
54 flat1 = Flatten()(model.layers[-1].output)
55 class1 = Dense(128, activation='relu', kernel_initializer='he_uniform')(flat1)
56 output = Dense(out_shape, activation='sigmoid')(class1)
57 # define new model
58 model = Model(inputs=model.inputs, outputs=output)
59 # compile model
60 opt = SGD(lr=0.01, momentum=0.9)
61 model.compile(optimizer=opt, loss='binary_crossentropy', metrics=[fbeta])
62 return model
63
64# plot diagnostic learning curves
65def summarize_diagnostics(history):
66 # plot loss
67 pyplot.subplot(211)
68 pyplot.title('Cross Entropy Loss')
69 pyplot.plot(history.history['loss'], color='blue', label='train')
70 pyplot.plot(history.history['val_loss'], color='orange', label='test')
71 # plot accuracy
72 pyplot.subplot(212)
73 pyplot.title('Fbeta')
74 pyplot.plot(history.history['fbeta'], color='blue', label='train')
75 pyplot.plot(history.history['val_fbeta'], color='orange', label='test')
76 # save plot to file
77 filename = sys.argv[0].split('/')[-1]
78 pyplot.savefig(filename '_plot.png')
79 pyplot.close()
80
81# run the test harness for evaluating a model
82def run_test_harness():
83 # load dataset
84 trainX, trainY, testX, testY = load_dataset()
85 # create data generator
86 train_datagen = ImageDataGenerator(featurewise_center=True, horizontal_flip=True, vertical_flip=True, rotation_range=90)
87 test_datagen = ImageDataGenerator(featurewise_center=True)
88 # specify imagenet mean values for centering
89 train_datagen.mean = [123.68, 116.779, 103.939]
90 test_datagen.mean = [123.68, 116.779, 103.939]
91 # prepare iterators
92 train_it = train_datagen.flow(trainX, trainY, batch_size=128)
93 test_it = test_datagen.flow(testX, testY, batch_size=128)
94 # define model
95 model = define_model()
96 # fit model
97 history = model.fit_generator(train_it, steps_per_epoch=len(train_it),
98 validation_data=test_it, validation_steps=len(test_it), epochs=50, verbose=0)
99 # evaluate model
100 loss, fbeta = model.evaluate_generator(test_it, steps=len(test_it), verbose=0)
101 print('> loss=%.3f, fbeta=%.3f' % (loss, fbeta))
102 # learning curves
103 summarize_diagnostics(history)
104
105# entry point, run the test harness
106run_test_harness()
首先运行示例适合模型,然后在保持测试数据集上报告模型性能。
鉴于学习算法的随机性,您的具体结果可能会有所不同。
在这种情况下,我们可以看到模型性能进一步提高,从F-beta评分约0.879提高到F-beta评分约0.891。
回顾学习曲线,我们可以看到数据的增加再次对模型的过拟合产生了很大的影响,在这种情况下稳定了学习,并可能将过拟合延迟到20 epoch。
讨论 在本节中,我们探讨了三种不同的迁移学习案例。 结果总结如下,尽管我们必须假设学习算法的随机性质,这些结果有一些差异:
- VGG-16模型:0.860。
- VGG-16模型 微调:0.879。
- VGG-16模型 微调 数据扩充:0.891。
VGG-16模型的选择有些武断,因为它是一个较小的、易于理解的模型。其他模型可以作为转移学习的基础,例如ResNet,它可以获得更好的性能。
此外,更多的微调也可能导致更好的性能。这可能包括调整更多特征提取器层的权重,可能会降低学习速度。这还可能包括修改模型以添加正则化,例如dropout。
如何确定模型并做出预测
只要我们有想法,有时间和资源去测试它们,模型改进的过程就会持续下去。
在某些时候,必须选择并采用最终的模型配置。在本例中,我们将保持简单,并使用VGG-16转移学习,微调和数据增强作为最终模型。
首先,我们将通过在整个训练数据集上拟合模型并将模型保存到文件以供以后使用来完成我们的模型。然后,我们将加载已保存的模型并使用它来对单个图像进行预测。
保存最终模型
第一步是在整个训练数据集上拟合最终模型。 所述load_dataset()函数可以被更新到加载的数据集不再分成训练集和测试集。
代码语言:javascript复制1# load train and test dataset
2def load_dataset():
3 # load dataset
4 data = load('planet_data.npz')
5 X, y = data['arr_0'], data['arr_1']
6 return X, y
所述define_model()函数可以被用作前一节与微调和数据扩张中VGG-16模型中被定义。
代码语言:javascript复制 1# define cnn model
2def define_model(in_shape=(128, 128, 3), out_shape=17):
3 # load model
4 model = VGG16(include_top=False, input_shape=in_shape)
5 # mark loaded layers as not trainable
6 for layer in model.layers:
7 layer.trainable = False
8 # allow last vgg block to be trainable
9 model.get_layer('block5_conv1').trainable = True
10 model.get_layer('block5_conv2').trainable = True
11 model.get_layer('block5_conv3').trainable = True
12 model.get_layer('block5_pool').trainable = True
13 # add new classifier layers
14 flat1 = Flatten()(model.layers[-1].output)
15 class1 = Dense(128, activation='relu', kernel_initializer='he_uniform')(flat1)
16 output = Dense(out_shape, activation='sigmoid')(class1)
17 # define new model
18 model = Model(inputs=model.inputs, outputs=output)
19 # compile model
20 opt = SGD(lr=0.01, momentum=0.9)
21 model.compile(optimizer=opt, loss='binary_crossentropy')
22 return model
最后,对于训练数据集,我们只需要一个数据生成器和一个迭代器。
代码语言:javascript复制1# create data generator
2datagen = ImageDataGenerator(featurewise_center=True, horizontal_flip=True, vertical_flip=True, rotation_range=90)
3# specify imagenet mean values for centering
4datagen.mean = [123.68, 116.779, 103.939]
5# prepare iterator
6train_it = datagen.flow(X, y, batch_size=128)
该模型将适用于50个epoch,之后通过调用模型上的save()函数将其保存到H5文件中
代码语言:javascript复制1# fit model
2model.fit_generator(train_it, steps_per_epoch=len(train_it), epochs=50, verbose=0)
3# save model
4model.save('final_model.h5')
注意:保存和加载Keras模型需要在工作站上安装h5py库。 下面列出了将最终模型拟合到训练数据集并将其保存到文件的完整示例。
代码语言:javascript复制 1# save the final model to file
2from numpy import load
3from keras.preprocessing.image import ImageDataGenerator
4from keras.applications.vgg16 import VGG16
5from keras.models import Model
6from keras.layers import Dense
7from keras.layers import Flatten
8from keras.optimizers import SGD
9
10# load train and test dataset
11def load_dataset():
12 # load dataset
13 data = load('planet_data.npz')
14 X, y = data['arr_0'], data['arr_1']
15 return X, y
16
17# define cnn model
18def define_model(in_shape=(128, 128, 3), out_shape=17):
19 # load model
20 model = VGG16(include_top=False, input_shape=in_shape)
21 # mark loaded layers as not trainable
22 for layer in model.layers:
23 layer.trainable = False
24 # allow last vgg block to be trainable
25 model.get_layer('block5_conv1').trainable = True
26 model.get_layer('block5_conv2').trainable = True
27 model.get_layer('block5_conv3').trainable = True
28 model.get_layer('block5_pool').trainable = True
29 # add new classifier layers
30 flat1 = Flatten()(model.layers[-1].output)
31 class1 = Dense(128, activation='relu', kernel_initializer='he_uniform')(flat1)
32 output = Dense(out_shape, activation='sigmoid')(class1)
33 # define new model
34 model = Model(inputs=model.inputs, outputs=output)
35 # compile model
36 opt = SGD(lr=0.01, momentum=0.9)
37 model.compile(optimizer=opt, loss='binary_crossentropy')
38 return model
39
40# run the test harness for evaluating a model
41def run_test_harness():
42 # load dataset
43 X, y = load_dataset()
44 # create data generator
45 datagen = ImageDataGenerator(featurewise_center=True, horizontal_flip=True, vertical_flip=True, rotation_range=90)
46 # specify imagenet mean values for centering
47 datagen.mean = [123.68, 116.779, 103.939]
48 # prepare iterator
49 train_it = datagen.flow(X, y, batch_size=128)
50 # define model
51 model = define_model()
52 # fit model
53 model.fit_generator(train_it, steps_per_epoch=len(train_it), epochs=50, verbose=0)
54 # save model
55 model.save('final_model.h5')
56
57# entry point, run the test harness
58run_test_harness()
运行此示例后,您将在当前工作目录中将拥有一个91兆字节的大文件,名为final_model。
做一个预测
我们可以使用我们保存的模型对新图像进行预测。 该模型假设新图像是彩色的,并且它们已被分割成大小为256×256的正方形。 下面是从训练数据集中提取的图像。
将其从训练数据目录复制到名为“ sample_image.jpg ” 的当前工作目录,例如:
根据训练数据集的映射文件,该文件具有标记(没有特定的顺序):
- 农业
- 水
我们将假装这是一个全新的,看不见的图像,以所需的方式准备,并看看我们如何使用我们保存的模型来预测图像所代表的标签。
首先,我们可以加载图像并将其强制为128×128像素。然后可以调整加载的图像的大小以在数据集中具有单个样本。像素值也必须居中以匹配在模型训练期间准备数据的方式。
该load_image()函数实现这一点,将返回加载图像准备进行分类。
代码语言:javascript复制 1# load and prepare the image
2def load_image(filename):
3 # load the image
4 img = load_img(filename, target_size=(128, 128))
5 # convert to array
6 img = img_to_array(img)
7 # reshape into a single sample with 3 channels
8 img = img.reshape(1, 128, 128, 3)
9 # center pixel data
10 img = img.astype('float32')
11 img = img - [123.68, 116.779, 103.939]
12 return img
接下来,我们可以像上一节一样加载模型,并调用predict()函数来预测图像中的内容。
代码语言:javascript复制1# predict the class
2result = model.predict(img)
这将返回一个包含17个元素的向量,其浮点值介于0和1之间,可以将其解释为模型确信照片可以用每个已知标记标记的概率。 我们可以将这些概率舍入为0或1,然后使用我们在create_tag_mapping()函数的第一部分中准备的反向映射,将具有“ 1 ”值的矢量索引转换为图像的标记。
下面的prediction_to_tags()函数实现了这一点,将整数映射到标签和照片模型预测的向量,并返回预测的标签列表。
代码语言:javascript复制1# convert a prediction to tags
2def prediction_to_tags(inv_mapping, prediction):
3 # round probabilities to {0, 1}
4 values = prediction.round()
5 # collect all predicted tags
6 tags = [inv_mapping[i] for i in range(len(values)) if values[i] == 1.0]
7 return tags
我们可以将所有这些结合在一起并对新照片进行预测。下面列出了完整的示例。
代码语言:javascript复制 1# make a prediction for a new image
2from pandas import read_csv
3from keras.preprocessing.image import load_img
4from keras.preprocessing.image import img_to_array
5from keras.models import load_model
6
7# create a mapping of tags to integers given the loaded mapping file
8def create_tag_mapping(mapping_csv):
9 # create a set of all known tags
10 labels = set()
11 for i in range(len(mapping_csv)):
12 # convert spaced separated tags into an array of tags
13 tags = mapping_csv['tags'][i].split(' ')
14 # add tags to the set of known labels
15 labels.update(tags)
16 # convert set of labels to a list to list
17 labels = list(labels)
18 # order set alphabetically
19 labels.sort()
20 # dict that maps labels to integers, and the reverse
21 labels_map = {labels[i]:i for i in range(len(labels))}
22 inv_labels_map = {i:labels[i] for i in range(len(labels))}
23 return labels_map, inv_labels_map
24
25# convert a prediction to tags
26def prediction_to_tags(inv_mapping, prediction):
27 # round probabilities to {0, 1}
28 values = prediction.round()
29 # collect all predicted tags
30 tags = [inv_mapping[i] for i in range(len(values)) if values[i] == 1.0]
31 return tags
32
33# load and prepare the image
34def load_image(filename):
35 # load the image
36 img = load_img(filename, target_size=(128, 128))
37 # convert to array
38 img = img_to_array(img)
39 # reshape into a single sample with 3 channels
40 img = img.reshape(1, 128, 128, 3)
41 # center pixel data
42 img = img.astype('float32')
43 img = img - [123.68, 116.779, 103.939]
44 return img
45
46# load an image and predict the class
47def run_example(inv_mapping):
48 # load the image
49 img = load_image('sample_image.jpg')
50 # load model
51 model = load_model('final_model.h5')
52 # predict the class
53 result = model.predict(img)
54 print(result[0])
55 # map prediction to tags
56 tags = prediction_to_tags(inv_mapping, result[0])
57 print(tags)
58
59# load the mapping file
60filename = 'train_v2.csv'
61mapping_csv = read_csv(filename)
62# create a mapping of tags to integers
63_, inv_mapping = create_tag_mapping(mapping_csv)
64# entry point, run the example
65run_example(inv_mapping)
运行示例首先加载并准备图像,加载模型,然后进行预测。 首先,打印原始17元素预测向量。如果我们愿意,我们可以漂亮地打印这个矢量并总结出照片将被分配到每个标签的预期置信度。
接下来,对预测进行舍入,并将包含1值的向量索引反向映射到其标记字符串值。然后打印预测的标签。我们可以看到模型已正确预测所提供照片的已知标签。
在您已经手动建议标签后,使用全新照片(例如测试数据集中的照片)重复此测试可能会很有趣。
扩展
本节列出了一些扩展您可能希望探索的教程的想法。
- 调整学习速率。探索用于训练基准模型的学习算法的更改,如替代学习速率、学习率调度或自适应学习率算法(如Adam)。
- 规范迁移学习模型。探索在迁移学习中添加更多的正则化技术,如early topping、dropout、weight decay等,并比较结果。
- 自动化测试时间。更新模型以使用测试时间预测,例如flips, rotations, and/or crops,以查看测试数据集上的预测性能是否可以进一步提高。
写在最后:
文章终于翻译完了,这两个周只要有时间就会翻译文章,自己水平有限,文章中可能会存在很多问题,欢迎您在留言区跟我交流,如果翻译的文章对您有用,我以后还会继续翻译文章。翻译这篇文章被老外的思维所折服,以后写此类文章会加以学习。
原文传送门:
https://machinelearningmastery.com/how-to-develop-a-convolutional-neural-network-to-classify-satellite-photos-of-the-amazon-rainforest/