学完了CNN的基本构件,让我们用TensorFlow来搭建一个CNN,并用这个网络完成之前那个简单的猫狗分类任务。
项目网址:https://github.com/SingleZombie/DL-Demos/tree/master/dldemos/BasicCNN
获取数据集
和之前几次的代码实战任务一样,我们这次还用的是Kaggle上的猫狗数据集。我已经写好了数据预处理的函数。使用如下的接口即可获取数据集:
train_X, train_Y, test_X, test_Y = get_cat_set(
'dldemos/LogisticRegression/data/archive/dataset', train_size=1500)
print(train_X.shape) # (m, 224, 224, 3)
print(train_Y.shape) # (m , 1)
这次的数据格式和之前项目中的有一些区别。
在使用全连接网络时,每一个输入样本都是一个一维向量。在预处理数据集时,我就做了一个flatten操作,把图片的所有颜色值塞进了一维向量中。而在CNN中,对于卷积操作,每一个输入样本都是一个三维张量。在用OpenCV读取完图片后,不用对图片Resize,直接拿过来用就可以了。
另外,在用NumPy实现时,我们把数据集大小m
当作了最后一个参数。而TensorFlow默认张量是"NHWC(数量-高度-宽度-通道数)"格式。在此项目中,我们是按照TensorFlow的格式预处理数据的。
初始化模型
根据课堂里讲的CNN构建思路,我搭了一个这样的网络。
由于这个二分类任务比较简单,我在设计时尽可能让可训练参数更少。刚开始用一个大步幅、大卷积核的卷积快速缩小图片边长,之后逐步让图片边长减半、深度翻倍。
这样一个网络用TensorFlow实现如下:
def init_model(input_shape=(224, 224, 3)):
model = tf.keras.Sequential([
tf.keras.layers.Conv2D(16, 11, (