利用kaggle提供的免费GPU训练自己的神经网络(猫狗大战数据集)
1.前言
kaggle是一个社区,一个平台,他提供了每周至少30个小时的免费GPU并且这个GPU的性能十分不错,看价格直接就能把我说服
对于硬件不好的同学(毕竟不是谁都不想刚入门就买个这么贵的),是个非常不错的选择。
2.数据集选择
这里我们用的是著名的猫狗大战数据集,即一堆猫和狗的图片,经典的二分类问题,但是要注意这里的图片都是不一样大小的彩色图,这决定了我们之后需要规范图片的大小
3.读取数据并作预处理
这里我们数据集都上传到了kaggle上,直接添加就好了(如何添加查看博主的过去的博客),然后我们读取图片并作规范化处理,具体步骤就是获得图片的地址,读取图片,改变图片尺寸,对图片做归一化处理,
import tensorflow as tf
from tensorflow import keras
from keras import layers
import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np
import glob
import os
train_image_path=glob.glob('../input/dog-vs-cat/dc/train/*.jpg')
train_image_path[-5:]
['../input/dog-vs-cat/dc/train/cat.3664.jpg',
'../input/dog-vs-cat/dc/train/dog.1783.jpg',
'../input/dog-vs-cat/dc/train/dog.9392.jpg',
'../input/dog-vs-cat/dc/train/dog.1631.jpg',
'../input/dog-vs-cat/dc/train/dog.6938.jpg']
我们通过查看图片可以发现图片的标签被标记到的位置,我们制造一个列表来存储(这里用了一个简写来创造列表)
train_labels=[s.split('/')[5].split('.')[0] for s in train_image_path]
train_labels[-5:]
['cat', 'dog', 'dog', 'dog', 'dog']
但我们在真正训练的时候不可能用英文单词去学习,所以我们要将单词赋予特定的数字标签
#提取每张图片的标签
label_to_index={'dog':0,'cat':1}
train_labels_nums=[label_to_index.get(l) for l in train_labels]
#将标签转化成数字方便我们处理
def load_img(path,label):#加载图片函数
img=tf.io.read_file(path)
img=tf.image.decode_jpeg(img,channels=3)
img=tf.image.resize(img,[256,256])#将图像扭曲并不影响我们对于图像的判断
img=tf.cast(img,tf.float32)
img=img/255
label=tf.reshape(label,[1])#将数据转化为每个一维的数据
#处理图像数据,使用这个函数如果图像数据类型不是float它会自动做归一化
return img,label
train_data=tf.data.Dataset.from_tensor_slices((train_image_path,train_labels_nums))
train_data=train_data.map(load_img)#利用该方法转化数据
train_data
<MapDataset shapes: ((256, 256, 3), (1,)), types: (tf.float32, tf.int32)>
BATCH_SIZE=16#如果CPU好点batch_size可以大点
train_count=len(train_image_path)
train_data=train_data.shuffle(1000).batch(BATCH_SIZE)
4.搭建模型与开始训练
这里就直接搭建模型了,不作详细的解释了
model=keras.Sequential()
model.add(layers.Conv2D(64,(3,3),input_shape=(256,256,3),activation='relu'))
model.add(layers.MaxPooling2D())
model.add(layers.Conv2D(128,(3,3),activation='relu'))
model.add(layers.MaxPooling2D())
model.add(layers.Conv2D(256,(3,3),activation='relu'))
model.add(layers.MaxPooling2D())
model.add(layers.Conv2D(512,(3,3),activation='relu'))
model.add(layers.MaxPooling2D())
model.add(layers.Conv2D(1024,(3,3),activation='relu'))
model.add(layers.GlobalAveragePooling2D())
model.add(layers.Dense(256,activation='relu'))
model.add(layers.Dense(1,activation='sigmoid'))#可激活也可不激活只要对输出了解可以修改
然后我们在这里使用自定义的内容来训练,所以我们自己定义优化器损失函数,评价参数accuracy,loss
optimizer=keras.optimizers.Adam()
train_loss=keras.metrics.Mean('train_loss')
train_accuracy=keras.metrics.Accuracy()
def train_step(model,images,lables):
with tf.GradientTape() as t:
pred=model(images)
loss_step=keras.losses.BinaryCrossentropy()(labels,pred)
gradies=t.gradient(loss_step,model.trainable_variables)#求解梯度
optimizer.apply_gradients(zip(gradies,model.trainable_variables))#将梯度应用于优化器从而让模型的可训练参数改变
train_loss(loss_step)
pred=tf.cast(pred>0.5,tf.int32)
train_accuracy(labels,pred)
开始训练,
all_loss=[]
all_accuracy=[]
for epoch in range(10):
for imgs,labels in train_data:
train_step(model,imgs,labels)
print('-',end='')#标志训练完一个batch
print('>')
print()
all_loss.append(train_loss.result())
all_accuracy.append(train_accuracy.result())
print('Epoch {}: loss: {:.3f}, accuracy: {:.3f}'.format(epoch+1,train_loss.result(),train_accuracy.result()))#查看每一步的训练的结果
train_loss.reset_states()#重新设置状态
train_accuracy.reset_states()
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------>
Epoch 1: loss: 0.238, accuracy: 0.900
这里显示出一部分结果(这里由于,我没注意所以一行输出太多了。。。截取一部分就好了),最后我们直接使用测试集上的数据来验证
import random
#随机选取一张图片从而来保证每次数据都会不同
ch=random.choice(range(len(test_image_path)))
path=test_image_path[ch]
img=load_img(path)
plt.imshow(img)
img=tf.expand_dims(img,0)
pred=model(img)
pred=pred.numpy()
judge=tf.cast(pred>0.5,tf.int32).numpy()
pred=judge.reshape(1)
plt.title(index_to_label.get(pred[0]))
可以看出来,我们的训练的模型正确率是十分高的
5.结束语
在本节中我们介绍了如何在kaggle上面的训练模型来识别猫狗数据及
烦点个赞,或者本文哪里有错误或者有什么疑问的可以在评论区里交流,谢谢。