在上一部分中,我们讲解了tensorflow2.0的简单应用,会建立简单的NN,CNN模型。我们了解了如何使用CNN来提高对手写数字的识别效率。 在本部分,我们将把它带入一个新的水平,识别猫和狗的真实图像,以便将传入的图像分类为一个或另一个。 尤其是手写识别功能,因为所有图像均具有相同的大小和形状,并且均为单色,因此使的处理很简单。现实世界中的图像并非如此—它们具有不同的形状,宽高比等,而且通常是彩色的!同时,这一部分,我们也会讲解一下在具体应用中我们会遇到的问题,如过拟合,欠拟合等。
我们先按前面的知识点写一个猫狗二分类的模型,这里的图像与现实世界中的图像一致-------它们具有不同的形状,宽高比等,而且通常是彩色的!
因此,作为任务的一部分,需要处理数据—尤其是将其大小调整为一致的形状。
步骤如下:
以下python代码将使用OS库来使用操作系统库,从而使您可以访问文件系统,并使用zipfile库来解压缩数据。
import os
import tensorflow as tf
import zipfile
读取数据
local_zip = '/content/drive/My Drive/Colab Notebooks/DateSet/cats_and_dogs_filtered.zip'
zip_ref = zipfile.ZipFile(local_zip,'r')
zip_ref.extractall('/content/drive/My Drive/Colab Notebooks/tmp')
zip_ref.close
.zip的内容被提取到基本目录/tmp/cats_and_dogs_filtered中,该目录包含用于训练和验证数据集的训练和验证子目录,该目录依次包含猫和狗的子目录。
简而言之:训练集是用来告诉神经网络模型“这就是猫的样子”,“这就是狗的样子”等的数据。验证数据集是猫和狗的图像神经网络不会作为训练的一部分,因此可以测试在评估图像中是否包含猫或狗时,神经网络的效果如何。
在此示例中要注意的一件事:我们没有将图像明确标记为猫或狗。如果还记得上面的手写示例,我们将其标记为“这是1”,“这是7”等。稍后,您将看到正在使用的称为ImageGenerator的东西-编码为从子目录读取图像,并从该子目录的名称中自动标记它们。因此,例如,将有一个“train”目录,其中包含一个“猫”目录和一个“狗”目录。 ImageGenerator将为您适当地标记图像,从而减少了编码步骤。
让我们定义以下每个目录:
#起始路径
base_dir = '/content/drive/My Drive/Colab Notebooks/tmp/cats_and_dogs_filtered'
#训练集,验证集路径
train_dir = os.path.join(base_dir,'train')
validation_dir = os.path.join(base_dir,'validation')
#训练集猫狗路径
train_cats_dir = os.path.join(train_dir,'cats')
train_dogs_dir = os.path.join(train_dir,'dogs')
#验证集猫狗路径
validation_cats_dir = os.path.join(validation_dir, 'cats')
validation_dogs_dir = os.path.join(validation_dir, 'dogs')
现在,让我们看一下cats和dogs训练目录中的文件名是什么样的(验证目录中的文件命名约定是相同的):
train_cat_fnames = os.listdir(train_cats_dir)
train_dog_fnames = os.listdir(train_dogs_dir)
print(train_cat_fnames[:10])
print(train_dog_fnames[:10])
结果:
['cat.127.jpg', 'cat.126.jpg', 'cat.125.jpg', 'cat.124.jpg', 'cat.123.jpg', 'cat.122.jpg', 'cat.121.jpg', 'cat.120.jpg', 'cat.119.jpg', 'cat.118.jpg']
['dog.127.jpg', 'dog.126.jpg', 'dog.125.jpg', 'dog.124.jpg', 'dog.123.jpg', 'dog.122.jpg', 'dog.121.jpg', 'dog.120.jpg', 'dog.119.jpg', 'dog.118.jpg']
让我们查看训练集和验证目录中猫和狗的图像总数:
print('total training cat images :', len(os.listdir(train_cats_dir)))
print('total training dog images :', len(os.listdir(train_dogs_dir)))
print('total validation cat images :', len(os.listdir(validation_cats_dir)))
print('total validation dog images :', len(os.listdir(validation_dogs_dir)))
结果:
total training cat images : 1000
total training dog images : 1000
total validation cat images : 500
total validation dog images : 500
对于猫和狗,我们都有1000张训练图像和500张验证图像。 现在,让我们看一些图片,以更好地了解猫和狗数据集的外观。首先,配置matplot参数:
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
nrows = 4
ncols = 4
pic_index = 0
#输出8只猫,8只狗
fig = plt.gcf()
fig.set_size_inches(ncols*4,nrows*4) #图像大小
pic_index += 8
next_cat_pix = [ os.path.join(train_cats_dir,fname) for fname in train_cat_fnames[pic_index-8:pic_index] ]
next_dog_pix = [ os.path.join(train_dogs_dir,fname) for fname in train_dog_fnames[pic_index-8:pic_index] ]
#print(next_cat_pix[:10])
for i,img_path in enumerate(next_cat_pix+next_dog_pix):
sp = plt.subplot(nrows,ncols,i+1)
sp.axis('off')
img = mpimg.imread(img_path)
plt.imshow(img)
plt.show()
结果:
通过查看此网格中的图像可能不会很明显,但是这里需要注意的是,与上一课的显着区别是这些图像具有各种形状和大小。 在进行手写识别示例时,使用的是28x28灰度图像。这些是颜色,形状多样。在与他们一起训练神经网络之前,需要调整图像。 将在下一部分中看到。
好的,既然对数据的外观有所了解,那么下一步就是定义将要训练的模型,以从这些图像中识别猫或狗。
在上一节中,看到图像具有各种形状和大小。 为了训练神经网络来处理它们,需要它们具有统一的大小。 因此我们选择了150x150。
让我们开始定义模型:
我们将像之前一样定义一个顺序层,首先添加一些卷积层。 注意这次输入的形状参数。 在较早的示例中,它是28x28x1,因为图像的灰度是28x28(8位,色深1个字节)。 这次大小为150x150,颜色深度为3(24位,3字节)。
然后,像前面的示例一样,添加几个卷积层,并将最终结果展平接入全连接层。
最后,我们添加全连接的层。
请注意,由于我们面临两类分类问题,即二进制分类问题,因此我们将以S型激活来结束网络,以便网络的输出将是介于0和1之间的单个标量,从而编码。当前图像是1类(而不是0类)。
model = tf.keras.Sequential([
tf.keras.layers.Conv2D(16,(3,3),activation="relu",input_shape = (150,150,3)),
tf.keras.layers.MaxPool2D(2,2),
tf.keras.layers.Conv2D(32,(3,3),activation="relu"),
tf.keras.layers.MaxPool2D(2,2),
tf.keras.layers.Conv2D(64,(3,3),activation="relu"),
tf.keras.layers.MaxPool2D(2,2),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(512,activation="relu"),
tf.keras.layers.Dense(1,activation="sigmoid") ])
查看一下网络的结构
model.summary()
“Output Shape”列显示了要素地图的大小在每个连续的图层中如何演变。 卷积层由于填充而使特征图的大小略微减少,每个合并层将尺寸减半。
接下来,我们将配置模型训练的规范。 我们将使用binary_crossentropy损失训练模型,因为这是一个二进制分类问题,而我们的最终激活是sigmoid型。 我们将使用RMSprop优化器,其学习率为0.001。 在训练期间,我们将要监控分类的准确性。
注意:在这种情况下,使用RMSprop优化算法要优于随机梯度下降(SGD),因为RMSprop可以自动为我们调整学习速率。 (其他优化器,例如Adam和Adagrad,也可以在训练过程中自动调整学习率,并且在此处同样适用。)
from tensorflow.keras.optimizers import RMSprop
model.compile(optimizer=RMSprop(lr = 0.001),loss='binary_crossentropy',metrics=['acc'])
让我们设置数据生成器,该数据生成器将读取源文件夹中的图片,将其转换为float32张量,并将它们(带有标签)馈送到我们的网络中。我们将为训练图像提供一个生成器,为验证图像提供一个生成器。我们的生成器将批量生产20张大小为150x150的图像及其标签(二进制)。
进入神经网络的数据通常应该以某种方式进行规范化,以使其更适合网络处理。 (将原始像素输入到卷积图中是很罕见的。)在本例中,我们将通过将像素值标准化为[0,1]范围(最初所有值都在[0,255]范围内)来预处理图像)。
在Keras中,这可以通过keras.preprocessing.image.ImageDataGenerator类使用rescale参数来完成。使用此ImageDataGenerator类,可以通过.flow(数据,标签)或.flow_from_directory(目录)实例化增强图像批处理(及其标签)的生成器。然后,这些生成器可以与Keras模型方法一起使用,这些方法将数据生成器作为输入:fit_generator,evaluate_generator和predict_generator。
from tensorflow.keras.preprocessing.image import ImageDataGenerator
#规范化
train_datagen = ImageDataGenerator(rescale=1/255)
test_datagen = ImageDataGenerator(rescale=1/255)
#训练集图片生成器
train_generator = train_datagen.flow_from_directory(
train_dir,
batch_size = 20,
class_mode = 'binary',
target_size=(150,150))
#验证集图片生成器
validation_generator = test_datagen.flow_from_directory(
validation_dir,
batch_size = 20,
class_mode = 'binary',
target_size=(150,150))
结果:
Found 2000 images belonging to 2 classes.
Found 1000 images belonging to 2 classes.
train_generator 发现了2000张图片。属于2类
validation_generator发现了1000张图片。属于两类
让我们训练所有2000张图像15个周期,并验证所有1000张测试图像。
请注意每个周期的值。
每个时期您将看到4个值----损失,准确度,验证损失和验证准确度。
损失和准确性是训练进度的重要标志。 它正在猜测训练数据的分类,然后根据已知标签对其进行测量,然后计算结果。 准确性是正确猜测的一部分。 验证准确度是对训练中未使用的数据的测量。 如预期的那样会更低。 您将在本课程后面的过度拟合部分中了解为什么会发生这种情况。
history = model.fit_generator( train_generator,
validation_data=validation_generator,
steps_per_epoch=100,
epochs=15,
validation_steps=50,
)
模型训练好了,接下来就是运行模型了。
现在让我们看一下使用模型实际运行预测。 此代码将允许从文件系统中选择1个或多个文件,然后将其上传并在模型中运行它们,从而指示对象是狗还是猫。
import numpy as np
from google.colab import files
from keras.preprocessing import image
uploaded = files.upload()
for fn in uploaded.keys():
path = '/content/' + fn #上传文件的位置
img = image.load_img(path,target_size=(150,150)) #上传
x = image.img_to_array(img) #图片的数组格式
x = np.expand_dims(x,axis=0) #(1,150,150)
images = np.vstack([x]) #将x的数据垂直相加,详见下方例子
classes = model.predict(images,batch_size=10)
print(classes[0])
if classes[0]>0:
print(fn + " is a dog")
else:
print(fn + " is a cat")
"""
import numpy as np
In[4]:
a = np.array([[1,2,3]])
a.shape
Out[4]:
(1, 3)
In [5]:
b = np.array([[4,5,6]])
b.shape
Out[5]:
(1, 3)
In [6]:
c = np.vstack((a,b)) # 将两个(1,3)形状的数组按垂直方向叠加
print(c)
c.shape # 输出形状为(2,3)
[[1 2 3]
[4 5 6]]
Out[6]:
(2, 3)
In [7]:
a = np.array([[1],[2],[3]])
a.shape
Out[7]:
(3, 1)
In [9]:
b = np.array([[4],[5],[6]])
b.shape
Out[9]:
(3, 1)
In [10]:
c = np.vstack((a,b)) # 将两个(3,1)形状的数组按垂直方向叠加
print(c)
c.shape # 输出形状为(6,1)
[[1]
[2]
[3]
[4]
[5]
[6]]
Out[10]:
(6, 1)
"""
补充内容说完了,我们继续。。。。。。
我分别上传如下两张图片,测试一下结果。
结果:
为了感觉一下我们的卷积网络学习了哪些功能,要做的一件有趣的事情是可视化输入在卷积网络中的转换方式。
让我们从训练集中选择一张随机的猫或狗图像,然后生成一个图形,其中每一行都是图层的输出,而行中的每一幅图像都是该输出要素图中的特定过滤器。 重新运行此单元格以生成各种训练图像的中间表示。
import numpy as np
import random
from tensorflow.keras.preprocessing.image import img_to_array,load_img
#让我们定义一个新模型,该模型将图像作为输入,并在第一个模型之后输出先前模型中所有层的中间表示。
successive_outputs = [layer.output for layer in model.layers[1:]] #每层的情况
#print(successive_outputs)
#可视化模型
visualization_model = tf.keras.models.Model(inputs = model.input,outputs = successive_outputs)
#准备一个输入图像
cat_img_files = [os.path.join(train_cats_dir, f) for f in train_cat_fnames]
dog_img_files = [os.path.join(train_dogs_dir, f) for f in train_dog_fnames]
#随机选择一图象
img_path = random.choice(cat_img_files + dog_img_files)
#处理图像
img = load_img(img_path,target_size=(150,150))
#变为矩阵格式
x = img_to_array(img) #(150, 150, 3)
x = x.reshape( (1,) + x.shape) #(1, 150, 150, 3)
#规范化
x /= 255
#让我们通过网络运行图像,从而获得该图像的所有中间表示。
successive_feature_maps = visualization_model.predict(x)
#这些是图层的名称,因此可以将其作为绘图的一部分
layer_names = [layer.name for layer in model.layers]
#开始画图
for layer_name, feature_map in zip(layer_names, successive_feature_maps):
if len(feature_map.shape) == 4:
# 只需对conv / maxpool层执行此操作,而不对完全连接的层执行此操作
n_features = feature_map.shape[-1] # 图像中元素的个数
size = feature_map.shape[1] # feature map shape (1, size, size, n_features)
# 我们将在此矩阵中平铺图像
display_grid = np.zeros((size, size * n_features))
# 对特征进行处理以使其可以观察
for i in range(n_features):
x = feature_map[0, :, :, i]
x -= x.mean()
x /= x.std ()
x *= 64
x += 128
x = np.clip(x, 0, 255).astype('uint8')
display_grid[:,i*size:(i+1)*size] = x
scale = 20. / n_features
plt.figure( figsize=(scale * n_features, scale) )
plt.title ( layer_name )
plt.grid ( False )
plt.imshow( display_grid, aspect='auto', cmap='viridis' )
结果:
正如所见,从图像的原始像素过渡到越来越抽象和紧凑的表示形式。 下面的表示开始突出显示网络要注意的内容,并且显示“激活”的功能越来越少。 大多数设置为零。 这称为“稀疏”。 表示稀疏性是深度学习的关键特征。
这些表示所携带的关于图像原始像素的信息越来越少,但是携带的有关图像类别的信息却越来越精细。 可以将卷积网络(或通常称为深层网络)视为信息蒸馏管道。
让我们绘制训练期间收集的训练/验证准确性和损失:
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
#得到迭代次数
epochs = range(len(acc))
#画图
plt.plot(epochs,acc)
plt.plot(epochs,val_acc)
plt.title ('Training and validation accuracy')
plt.figure()
plt.plot ( epochs,loss )
plt.plot ( epochs,val_loss)
plt.title ('Training and validation loss' )
结果:
可以看到,我们过拟合了。我们的训练准确性(蓝色)接近100%,而我们的验证准确性(黄色)则停滞在70%。五个周期之后,我们的验证损失就达到了最小值。
由于我们的训练集数量相对较少(2000),因此过拟合应该是我们的头等大事。当暴露于过多示例的模型学习无法推广到新数据的模式时,即模型开始使用无关的功能进行预测时,就会发生过度拟合。例如,如果作为人类只看到三幅伐木工人的图像和三幅水手的图像,并且其中唯一戴着帽子的人是伐木工人,您可能会开始想到戴帽子是成为伐木工人而不是水手的标志。然后,做出一个非常糟糕的伐木工人/水手分类器。
过度拟合是机器学习中的核心问题:鉴于我们正在将模型的参数拟合到给定的数据集,我们如何确保模型学习的表示形式将适用于从未见过的数据?我们如何避免学习特定于训练数据的东西?
当我们数据很少时,我们不能准确的判断出两种或几种类别。这时,数据量的多少就显得至关重要了。
让我们继续从对学习Cats-Dogs模型开始。它与上面模型相似,但是我更新了图层定义。请注意,现在有4个卷积层,分别具有32、64、128和128个卷积。另外,这将训练100个周期,因为我想绘制损耗和精度图。
代码如下:
import os
import zipfile
import tensorflow as tf
from tensorflow.keras.optimizers import RMSprop
from tensorflow.keras.preprocessing.image import ImageDataGenerator
# local_zip = '/tmp/cats_and_dogs_filtered.zip'
# zip_ref = zipfile.ZipFile(local_zip, 'r')
# zip_ref.extractall('/tmp')
# zip_ref.close()
#起始路径
base_dir = '/content/drive/My Drive/Colab Notebooks/tmp/cats_and_dogs_filtered'
#训练集,验证集路径
train_dir = os.path.join(base_dir,'train')
validation_dir = os.path.join(base_dir,'validation')
#训练集猫狗路径
train_cats_dir = os.path.join(train_dir,'cats')
train_dogs_dir = os.path.join(train_dir,'dogs')
#验证集猫狗路径
validation_cats_dir = os.path.join(validation_dir, 'cats')
validation_dogs_dir = os.path.join(validation_dir, 'dogs')
model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(32, (3,3), activation='relu', input_shape=(150, 150, 3)),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Conv2D(128, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Conv2D(128, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(512, activation='relu'),
tf.keras.layers.Dense(1, activation='sigmoid')
])
model.compile(loss='binary_crossentropy',optimizer=RMSprop(lr=1e-4), metrics=['acc'])
# 规范化
train_datagen = ImageDataGenerator(rescale=1./255)
test_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(
train_dir,
target_size=(150, 150),
batch_size=20,
class_mode='binary')
validation_generator = test_datagen.flow_from_directory(
validation_dir,
target_size=(150, 150),
batch_size=20,
class_mode='binary')
history = model.fit_generator(
train_generator,
steps_per_epoch=100, # 2000 images = batch_size * steps
epochs=100,
validation_data=validation_generator,
validation_steps=50, # 1000 images = batch_size * steps
verbose=2)
import matplotlib.pyplot as plt
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = range(len(acc))
plt.plot(epochs, acc, 'bo', label='Training accuracy')
plt.plot(epochs, val_acc, 'b', label='Validation accuracy')
plt.title('Training and validation accuracy')
plt.figure()
plt.plot(epochs, loss, 'bo', label='Training Loss')
plt.plot(epochs, val_loss, 'b', label='Validation Loss')
plt.title('Training and validation loss')
plt.legend()
plt.show()
结果为:
我们可以看到,训练集准确度接近100%,验证准确度在70%-80%范围内。 这就是过度拟合的一个很好的例子—简而言之,这意味着它可以很好地处理以前看到的图像,但是不能很好地处理过以前没有看到的图像。 让我们看看是否可以做得更好,避免过度拟合的一种简单的方法是图片增强/数据增强。 考虑一下,大多数猫的照片都非常相似-耳朵在顶部,然后是眼睛,然后是嘴等。诸如眼睛和耳朵之间的距离之类的东西也总是非常相似。 如果我们对图像进行调整以稍微改变它,该怎么办—旋转图像,挤压图像等。这就是图像增强的全部内容。 现在看一下ImageGenerator。 一些属性可以用来实现图片增强。
train_datagen = ImageDataGenerator(
rescale = 1/255 #规范化
rotation_range=40,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
fill_mode='nearest')
相关参数:
rotation_range:一个值,单位为度(0–180),该范围是随机旋转图片的范围。rotation_range=40,旋转0–40中的随机度数。
width_shift/height_shift:在其中垂直或水平随机转换图片的范围(占总宽度或高度的一部分)。width_shift_range=0.2,随机移动20%的图片。
shear_range:用于随机应用剪切变换。shear_range=0.2,随机剪20%的图像。
zoom_range:用于随机放大图片。zoom_range=0.2,最大放大20%。
horizontal_flip:用于随机地水平翻转一半的图像。 当没有水平不对称性的假设时(例如真实图片),这是相关的。
fill_mode:是用于填充新创建的像素的策略,这些像素可以在旋转或宽度/高度偏移后出现。
这是一些我们添加了图像增强的代码。 运行它以查看影响。
import os
import zipfile
import tensorflow as tf
from tensorflow.keras.optimizers import RMSprop
from tensorflow.keras.preprocessing.image import ImageDataGenerator
# local_zip = '/tmp/cats_and_dogs_filtered.zip'
# zip_ref = zipfile.ZipFile(local_zip, 'r')
# zip_ref.extractall('/tmp')
# zip_ref.close()
#起始路径
base_dir = '/content/drive/My Drive/Colab Notebooks/tmp/cats_and_dogs_filtered'
#训练集,验证集路径
train_dir = os.path.join(base_dir,'train')
validation_dir = os.path.join(base_dir,'validation')
#训练集猫狗路径
train_cats_dir = os.path.join(train_dir,'cats')
train_dogs_dir = os.path.join(train_dir,'dogs')
#验证集猫狗路径
validation_cats_dir = os.path.join(validation_dir, 'cats')
validation_dogs_dir = os.path.join(validation_dir, 'dogs')
model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(32, (3,3), activation='relu', input_shape=(150, 150, 3)),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Conv2D(128, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Conv2D(128, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(512, activation='relu'),
tf.keras.layers.Dense(1, activation='sigmoid')
])
model.compile(loss='binary_crossentropy',
optimizer=RMSprop(lr=1e-4),
metrics=['acc'])
#训练集图片增强
train_datagen = ImageDataGenerator(
rescale=1./255,
rotation_range=40,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
fill_mode='nearest')
test_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(
train_dir,
target_size=(150, 150),
batch_size=20,
class_mode='binary')
validation_generator = test_datagen.flow_from_directory(
validation_dir,
target_size=(150, 150),
batch_size=20,
class_mode='binary')
history = model.fit_generator(
train_generator,
steps_per_epoch=100, # 2000 images = batch_size * steps
epochs=100,
validation_data=validation_generator,
validation_steps=50, # 1000 images = batch_size * steps
verbose=2)
结果:
图像增强完毕后,这时训练集与测试集的损失值和精度之间的关系如何呢?
import matplotlib.pyplot as plt
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = range(len(acc))
plt.plot(epochs, acc, 'bo', label='Training accuracy')
plt.plot(epochs, val_acc, 'b', label='Validation accuracy')
plt.title('Training and validation accuracy')
plt.figure()
plt.plot(epochs, loss, 'bo', label='Training Loss')
plt.plot(epochs, val_loss, 'b', label='Validation Loss')
plt.title('Training and validation loss')
plt.legend()
plt.show()
结果:
我们可以看到,验证集的精度和训练集大体一致,使得过拟合的情况消失了。
在次测验一样。我用如下两图测试,
注:ddd.jpg图使用一开始的模型进行测试时,给出的结果是dog,结果错误。我放入新模型还会出现这种错误嘛?来看一下。。。
import numpy as np
from google.colab import files
from keras.preprocessing import image
uploaded = files.upload()
for fn in uploaded.keys():
path = '/content/' + fn #上传文件的位置
img = image.load_img(path,target_size=(150,150)) #上传
x = image.img_to_array(img) #图片的数组格式
x = np.expand_dims(x,axis=0) #(1,150,150)
images = np.vstack([x]) #将x的数据垂直相加,详见下方例子
classes = model.predict(images,batch_size=10)
print(classes[0])
if classes[0]>0:
print(fn + " is a dog")
else:
print(fn + " is a cat")
结果:
在这个模型中,ddd.jpg成功的被分类为猫了。
最后的运行结果也要明显好于第一个模型。
这章主要讲解了什么叫过拟合,为什么会过拟合以及如何解决过拟合。
下章我们会继续从实际出发解决问题,敬请期待吧!(❤´艸`❤)