TensorFlow 模型建立与训练

TensorFlow 模型建立与训练

https://tf.wiki/zh/basic/models.html

如果程序报错,建议包含以下信息以帮助排除问题:

  • TensorFlow 版本(请检查 TensorFlow 版本为 2.0 及以上)
import tensorflow as tf
print (tf.__version__)
  • 完整的最小可运行程序代码(建议将代码在 IDE 中运行而不是交互式环境)
  • 完整的报错信息(Traceback)

根据 ‘“tf.matmul (input, kernel) + bias” ,y_pred = a * X + b 写成 y_pred = X * a + b 是不是更好,这样计算下来维度也是正确的

CNN 模型,我的正确率达到了 0.990600 MPL 正确率也比博主高,为什么我们会有差别呢

已经找到问题了。

建议可以把 debug 的过程发个帖分享一下看看是否可以帮到更多人~

nietzsche.txt (586.8 KB)

我下载了一份,你试试看先用着?

谢谢,刚刚解决了

1 Like

训练会受到一些随机因素的影响,CNN 的话 0.99 左右的准确率都是正常的,严谨一点的话可以多运行几次取均值。

请问卷积原理部分的权重剧中,为什么是给的那个,随机矩阵可以么,任何(0,1,2 或者只是 0,1)组成的的矩阵可以么,那个 w 矩阵是不是只是给定了一个规则

w 矩阵是表示卷积核中的权值,一般是通过模型训练得到的。

使用 cats_vs_dogs 数据集,按照下面的模型结构训练 CNN,10 个 epochs 的训练时间将近 3 个小时,请问这个正常吗?

model = tf.keras.Sequential ([
    tf.keras.layers.Conv2D (32, 3, activation='relu', input_shape=(256, 256, 3)),
    tf.keras.layers.MaxPooling2D (),
    tf.keras.layers.Conv2D (32, 5, activation='relu'),
    tf.keras.layers.MaxPooling2D (),
    tf.keras.layers.Flatten (),
    tf.keras.layers.Dense (64, activation='relu'),
    tf.keras.layers.Dense (2, activation='softmax')
])

请提供你的电脑的配置信息。如果有 NVIDIA 显卡的话请检查相应的环境是否配置好(见安装一章的说明)。直接在 CPU 上训练卷积神经网络的话确实速度会比较慢。

1 Like

电脑配置信息是:CPU i7 2.2, 内存 16GB, GPU Intel Iris Pro 1536Mb。按照上面的模型结构在训练完成之后模型的大小是 91MB,我尝试通过减少一层卷积层来减小模型的容量,但是只有一层 CNN 的模型训练得到的模型容量一下飙升到了 396 MB ,请问为什么模型结构简单了,相同的数据训练时间没有减少,容量反而增大了呢?

如果希望较快速地训练模型的话,可以考虑各种云平台,如 Google 免费的 Colab 或国内的云服务,参考 https://tf.wiki/zh/appendix/cloud.html

模型容量变大的话,我估计主要是因为最后一层的全连接层变大了。去掉了一层卷积层之后,后面的层的参数个数都会变化。

调整模型的哪些方面能让模型的容量更小呢?我尝试过减少卷积层,和调整 epochs,前者没有明显的改善,反而变大了;后者虽然稍有改善,但是损失了一些精度。正在使用的模型只有一层 64 个 units 的全连接层和一个输出层,因此没有考虑删掉这个全连接层。

“模型的容量”(拟合各种函数的能力)这个说法其实比较模糊,一般认为是和模型的参数数量高度相关。如果想要模型的参数更少的话,可以减少卷积核和神经元个数,以及想办法降低最后一层全连接层的参数数量。关于参数个数的计算方式可参考 https://zhuanlan.zhihu.com/p/77471991

不过如果你实际想要的是让模型训练的速度更快的话,其实最直白的方法是使用 GPU。cats_vs_dogs 数据集相对比较大,而卷积神经网络用 CPU 来训练其实效率非常低下(在大数据集上尤为明显)。这个模型在一个普通性能的 GPU 上(比如 GTX1060)应该几分钟就能训练好。

使用 cats_vs_dogs 数据集在第一轮 epoch 训练时,日志信息显示的训练进度是 “44/Unknown”,第二轮可以正常显示训练的数量 “34/776”,请问为什么这里第一轮是 Unknown 呢?训练数据我已下载到本地,加载方式:
train_cat_filenames = tf.constant ([train_cats_dir + filename for filename in os.listdir (train_cats_dir)])
train_dog_filenames = tf.constant ([train_dogs_dir + filename for filename in os.listdir (train_dogs_dir)])
train_dataset = tf.data.Dataset.from_tensor_slices ((train_filenames, train_labels))
train_dataset = train_dataset.map (
map_func=_decode_and_resize,
num_parallel_calls=tf.data.experimental.AUTOTUNE)
train_dataset = train_dataset.shuffle (buffer_size=23000)
train_dataset = train_dataset.batch (batch_size)
train_dataset = train_dataset.prefetch (tf.data.experimental.AUTOTUNE)

在 mnist 数据集的使用过程中,第一轮的 epoch 日志信息是可以正常显示进度的 “3520/60000”,mnist 的加载方式是通过:
mnist = tf.keras.datasets.mnist
(training_images, training_labels), (test_images, test_labels) = mnist.load_data ()

请问导致这种差别的原因是什么呢?会对训练得到的模型产生影响,破坏模型的可用性吗?

因为 cats_vs_dogs 数据集是用 tf.data 读取的。 tf.data.Dataset 作为一个针对大规模数据设计的迭代器,本身无法方便地获得自身元素的数量,只有迭代一遍之后才知道数据的总量(见 tf.data 一节里 “ Dataset.shuffle () 时缓冲区大小 buffer_size 的设置” 信息框)。数据量太大的时候,数一遍元素个数都是很费时的操作。对模型的训练一般没有什么影响。

在训练的过程中还弹出了 “Corrupt JPEG data: 2226 extraneous bytes before marker 0xd9” 这样的 warning, 经过调查发现可能是部分图片本身是 PNG 格式,但是却把后缀名强制改为 jpeg 导致的,这些报出 warning 的图片最终会参与到模型的训练中去吗?model.fit 对这样的内容的处理逻辑是什么样的?

使用 keras subclassing API 定义大模型的时候岂不是会特别臃肿,比如 ResNet150 一类的,因为需要在 init 中定义完全部使用的层并在 call 中指定它们之间的数据流动?