遇到的bug都放在之前的文章里了
import os
import pandas as pd
import warnings
import tensorflow as tf
from tensorflow.python import keras
from keras.preprocessing.image import ImageDataGenerator
import keras.optimizers as op
from tensorflow.python.keras import layers
from sklearn.model_selection import train_test_split
from keras.applications.resnet import ResNet101
from keras.applications.inception_v3 import InceptionV3
import matplotlib.pyplot as plt
#制定好数据的路径(训练和验证的数据集)
base_dir=r'G:\pycharm\tensorflow_learning\dogandcat\dogs-vs-cats'
test_dir=os.path.join(base_dir,'test1')
train_dir=os.path.join(base_dir,'train')
#读取测试集的所有图片,分类打上标签
filenames = os.listdir(train_dir)
categories = []
for filename in filenames:
category = filename.split('.')[0]
if category == 'dog':
categories.append(str(1))
else:
categories.append(str(0))
df= pd.DataFrame({
'filename': filenames,
'category': categories
})
#从测试集上划分训练集和验证集
x_train, x_val = train_test_split(df, test_size=0.2, random_state=2)
x_train = x_train.reset_index(drop=True)
x_val = x_val.reset_index(drop=True)
#数据预处理操作,读取数据,利用现有的图片数据,进行数加强,增加样本量
train_datagen = ImageDataGenerator(
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',
rescale=1./255)
valid_datagen = ImageDataGenerator(
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',
rescale=1./255)
train_generator = train_datagen.flow_from_dataframe(
x_train,
train_dir,
x_col='filename',
y_col='category',
target_size=(128,128),
class_mode="categorical",
)
valid_generator = valid_datagen.flow_from_dataframe(
x_val,
train_dir,
x_col='filename',
y_col='category',
target_size=(128,128),
class_mode="categorical",
)
#架构网络模型,使用卷积网络进行分类
'''
#准确率只有0.6
model=keras.models.Sequential([
layers.Conv2D(32,(3,3),activation='relu',input_shape=(128,128,3)),
layers.MaxPool2D(2,2),
layers.Conv2D(64,(3,3),activation='relu'),
layers.MaxPool2D(2,2),
layers.Conv2D(128,(3,3),activation='relu'),
layers.MaxPool2D(2,2),
#为全连接层做准备
layers.Flatten(),
layers.Dense(512,activation='relu'),
#使用sigmoid进行二分类
layers.Dense(2,activation='sigmoid')
])
'''
#模型优化:准确率达到0.71,上个模型会发生过拟合状况,所用我们使用了dropout
''''
tensorflow.keras.applications里面有许多训练好的模型可以直接使用
训练好的模型可以直接导入,如下
from keras.applications.resnet import ResNet101
from keras.applications.inception_v3 import InceptionV3
'''
pre_train_model=ResNet101(input_shape=(128,128,3),#输入大小,每一种预置的训练模型的输入数据都有要求我们需要自己去看API更具要求去选择合适的输入形状
include_top=False,#设置不要最后的连接层
weights='imagenet'#权重None随机初始化,或者imagenet是别人训练好的权重可以直接使用,或者指定我们训练好的一个权重数据.h5文件,
)
#可以选择训练哪些层,
for layer in pre_train_model.layers:
layer.trainable=False#这里面的所有层的训练数据都不会更新,使用设定好的参数,
'''
callback的作用
相当于一个监视器,在训练过程中可以设置一些自定义项,比如提前停止,改变学习率等
callback[
如果连续两个epoch(patince=2),monitor是依据,还没有降低就停止:
tf.keras.callbacks.EarlyStoping(patince=2,monitor='val_loss'),
可以动态改变学习率:
tf.keras.callbacks.LearningRateScheduler
保存模型:
tf.keras.callbacks.ModelCheckpoint
自定义方法
tf.keras.callbacks.Callback
]
'''
class mycallback(keras.callbacks.Callback):
def on_epoch_end(self,epoch,logs={}):
if(logs.get('acc')>0.95):
print("\nReached 95% accuracy so cancelling training!")
self.model.stop_training=True
#为全连接层做准备
from keras import layers
x=layers.Flatten()(pre_train_model.output)
#x=layers.Flatten()(pre_train_model.output)
#x=layers.Flatten()(pre_train_model.output)
#加入全连接层
x=layers.Dense(1024,activation='relu')(x)
x=layers.Dropout(0.4)(x)
#输出层
x=layers.Dense(2,activation='sigmoid')(x)
model=keras.Model(pre_train_model.input,x)
model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['acc'])
callback=mycallback()
history = model.fit(train_generator, steps_per_epoch=100,epochs=40, verbose=1, validation_data=valid_generator,validation_steps=50,callbacks=[callback])
#保存模型
#model.save('cat_vs_dog.h5')
#将准确率和损失率画图显示出来
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = range(1, len(acc) + 1)
plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.legend()
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()