机器学习笔记(二十五)——Tensorflow 2(多分类)
本博客仅用于个人学习,不用于传播教学,主要是记自己能够看得懂的笔记(
学习知识来自:【吴恩达团队Tensorflow2.0实践系列课程第一课】TensorFlow2.0中基于TensorFlow2.0的人工智能、机器学习和深度学习简介及基础编程_哔哩哔哩_bilibili
多分类其实我们也做过了,包括老师也说很简单。比如人与马的程序,我们改成辨别石头剪刀布的程序。
首先,要把数据集改成多分类,用三个目录装三个不同类别的数据。然后将ImageDataGenerator的导入分类模式改为'categorical',神经网络最后一层Dense改为3个神经元,激活函数改为'softmax'。最后,将compile里面的Loss函数改为'categorical_crossentropy'。
基本就这些啦。
数据:train_data:
https://storage.googleapis.com/laurencemoroney-blog.appspot.com/rps.zip
test_data:
https://storage.googleapis.com/laurencemoroney-blog.appspot.com/rps-test-set.zip
代码:
from tensorflow.keras.preprocessing import image from tensorflow.keras.preprocessing.image import ImageDataGenerator as idg import tensorflow as tf import numpy as np import os from tensorflow.keras.optimizers import RMSprop class myCallback(tf.keras.callbacks.Callback): #Callback类的继承类 def on_epoch_end(self,epoch,logs={}): #重写on_epoch_end函数 if logs.get('val_loss')<10 and logs.get('val_accuracy')>0.80: print('\nReached 80% accuracy so canceling training.') self.model.stop_training=True #达到条件,停止训练 callback=myCallback() filepath=os.path.abspath(__file__) #获取本文件的绝对路径 filepath=os.path.dirname(filepath) #获取本文件的父目录 files=[] for root,dirs,files in os.walk(filepath+'/tmp/rps-test-set'): #获取rps-test-set目录下的所有文件名 used_up_variable=0 datagen=idg( #此处为增强数据的各种方法 rescale=1./255, #归一化 rotation_range=40, #随机旋转-40~40度 width_shift_range=0.2, #随机改变宽度20% height_shift_range=0.2, #随机改变高度20% shear_range=0.2, #随机倾斜裁剪20% zoom_range=0.2, #随机放大20% horizontal_flip=True, #随机翻转 fill_mode='nearest' #图像改变后,需要将像素重新填充,用最近像素的特征来填充 ) #数据增强的generator traingen=datagen.flow_from_directory( #训练数据集,并用文件夹名作为标签分类 filepath+'/tmp/rps', #数据集所在地址 target_size=(150,150), #自动生成150*150的图片 batch_size=10, #这个不能太大,不然会超内存,所以我这个程序运行得贼慢 class_mode='categorical' #多分类模式 ) valigen=datagen.flow_from_directory( #验证数据集 filepath+'/tmp/rps-vali-set', target_size=(150,150), batch_size=10, class_mode='categorical' ) model=tf.keras.Sequential([ tf.keras.layers.Conv2D(16,(3,3),activation='relu',input_shape=(150,150,3)), tf.keras.layers.MaxPooling2D(2,2), tf.keras.layers.Conv2D(32,(3,3),activation='relu'), tf.keras.layers.MaxPooling2D(2,2), tf.keras.layers.Conv2D(64,(3,3),activation='relu'), tf.keras.layers.MaxPooling2D(2,2), tf.keras.layers.Flatten(), tf.keras.layers.Dense(512,activation='relu'), tf.keras.layers.Dropout(0.2), tf.keras.layers.Dense(3,activation='softmax') ]) model.compile( optimizer=RMSprop(lr=0.0001), #新型优化器 loss='categorical_crossentropy', #多分类交叉熵 metrics=['accuracy'] ) print(model.summary()) model.fit( #训练模型 traingen, #训练数据集generator steps_per_epoch=252, #注意前面的batch_size,这两个乘起来要大于等于数据集个数 epochs=15, validation_data=valigen, #验证数据集generator validation_steps=38, #这个与验证数据集的batch_size也是一样,乘起来大于等于验证数据集个数 callbacks=[callback] ) for file in files: pat=filepath+'/tmp/rps-test-set/'+file # img=cv2.imdecode(np.fromfile(pat,dtype=np.uint8),-1) img=image.load_img(pat,target_size=(150,150)) #导入图像 x=image.img_to_array(img) #变成array类 imgs=np.expand_dims(x,axis=0) #增加一个维度 # imgs=np.vstack([imgs]) # imgs=imgs/255.0 #归一化 classes=model.predict(imgs,batch_size=10) print(file) print(classes[0]) #输出预测值
得到结果:
paper01.png
[0. 0. 1.]
paper02.png
[1. 0. 0.]
paper03.png
[0. 0. 1.]
paper04.png
[1. 0. 0.]
paper05.png
[1. 0. 0.]
rock01.png
[0. 1. 0.]
rock02.png
[0. 1. 0.]
rock03.png
[0. 1. 0.]
rock04.png
[0. 1. 0.]
rock05.png
[0. 1. 0.]
scissors01-00.png
[0. 0. 1.]
scissors01-26.png
[0. 0. 1.]
scissors02-00.png
[0. 0. 1.]
scissors02-30.png
[0. 0. 1.]
scissors03-00.png
[0. 0. 1.]
scissors03-30.png
[0. 0. 1.]
scissors04-00.png
[0. 0. 1.]
scissors04-30.png
[0. 0. 1.]
还不错啦。