上一篇文章说到参加kaggle中的Deepfake比赛中使用baseline模型进行数据集训练及提交评估分数,相信很多小伙伴迫不及待想自己动手搓一个网络来完成这项任务了吧,但是又无从下手。因此,这篇文章将带来如何构建一个CNN模型进行训练并完成任务。
CNN是什么?
CNN,即卷积神经网络(Convolutional Neural Network),是一种深度学习模型,广泛应用于图像识别、视频分析和自然语言处理等领域。CNN通过使用卷积层来提取输入数据的特征,然后通常还会使用池化层(Pooling Layers)来减少数据的空间维度,最后通过全连接层(Fully Connected Layers)来进行分类或其他任务。
CNN是怎么训练的?
CNN的卷积层中包含多个神经元,每个神经元中又包含了权重(w)以及偏置(b),还包含一个激活函数(相当于该神经元是否产生或产生多少输出,视具体函数而定),当你把所有权重及偏置更新到了一个合适的值时,整个网络就能准确地完成特定的任务了,网络更新的过程相当于是通过练习与反馈,使自身能学习到问题的解。
反馈的机制
训练过程中,通过输入一部分数据进神经网络,神经网络进行前向传播,完成输出时会比较预测的结果与真实结果之间的loss,此时再通过反向传播就可以计算loss与每个参数直接的梯度,顺着梯度的方向就是减小预测的结果与真实结果之间的loss的方向啦
下面一起来看看一个简单的实操样例吧:
import matplotlib.pyplot as plt
from IPython.display import set_matplotlib_formats
set_matplotlib_formats('svg')
#设置Matplotlib图形库的输出格式为SVG。SVG是一种矢量图形格式,可以在不失真的情况下缩放和调整大小。这个代码可以在Matplotlib绘图时使用,以确保输出的图形具有高质量和可伸缩性。
%matplotlib inline
x = np.linspace(0, 10, 100)
#通过定义均匀间隔创建数值序列。其实,需要指定间隔起始点、终止端,以及指定分隔值总数(包括起始点和终止点);最终函数返回间隔类均匀分布的数值序列。请看示例:
#np.linspace(start = 0, stop = 100, num = 5)
y = -3 * x + 4 + np.random.randint(-2, 2, size=100)#此处加入随机数是为了把数据离散化,更贴切真实数据
plt.scatter(x,y)
#设置初始权重和偏置
w = torch.ones(1, requires_grad=True)#requires_grad表示该Tensor需要求导
b = torch.ones(1, requires_grad=True)
x_tensor = torch.from_numpy(x)
y_tensor = torch.from_numpy(y)
#定义损失函数
def mse(label, pred):
diff = label - pred
return torch.sqrt((diff ** 2).mean())
#预测输出值pred
pred = x_tensor * w + b
loss = mse(y_tensor, pred)
#开始训练
for _ in range(300):
w = w.clone().detach().requires_grad_(True)
b = b.clone().detach().requires_grad_(True)
pred = x_tensor * w +b
loss = mse(y_tensor, pred)
print(loss)
#进行反向传播以更新参数
loss.backward()
w = w - w.grad * 0.01
b = b - b.grad * 0.01
pred = x_tensor * w + b
plt.scatter(x, y)
plt.plot(x, pred.data.numpy())
plt.legend(['y=-3x+4+randm(-2,2)', 'Network'])
该代码引用自https://www.kaggle.com/code/finlay/deepfake-ffdi-ch2/#%E8%87%AA%E5%8A%A8%E6%B1%82%E6%A2%AF%E5%BA%A6
感兴趣的同学可以调整一下更新参数的大小,即w = w - w.grad * 0.01 b = b - b.grad * 0.01中的0.01,这里代表的相当于神经网络的学习率,通过调整可以观察到loss不断震荡或是loss减小地慢,这是因为学习率设置不当,如果学习率过高,模型可能会在损失函数的最小值附近震荡,而不是收敛;如果学习率过低,模型的收敛速度会很慢。
注意,上面代码只是为了加深理解反馈,并不是神经网络!!!
开始创建一个简单的CNN网络试试能得多少分吧!
首先引入包
然后是数据集加载
定义模型以及构建网络
定义一下计算模型得分和进度显示
定义训练函数并开始训练
代码最终得分:
第一行就是自己的网络得出的分数,虽然感觉自己搓出来的简单网络不如大佬提出的残差网络,但是得到分数那一刻也是成就感满满,可能这也算是迈出深度学习的重要一步,继续努力吧!!
代码在这里:www.kaggle.com/code/xiangh… 部分模型分数预测是比赛的baseline中的代码,感谢代码作者。