损失函数 Loss、梯度 grad、参数 ω 和 学习率 lr 之间的关系

举一个简单的函数 y = x 2 y = x^2 y=x2,梯度为 g ( x ) = ∂ y ∂ x = 2 x g(x) = \frac{\partial{y}}{\partial{x}} = 2x g(x)=xy=2x。设学习率为 l r lr lr,那么

更新一次梯度后为: x 1 = x 0 − l r ∗ g ( x 0 ) = x 0 − l r ∗ 2 x 0 = ( 1 − 2 ∗ l r ) x 0 x_1 = x_0 - lr * g(x_0) = x_0 - lr * 2x_0 = (1 - 2 * lr)x_0 x1=x0lrg(x0)=x0lr2x0=(12lr)x0

更新 n 次后的梯度为 x n = ( 1 − 2 ∗ l r ) x n − 1 = ( 1 − 2 ∗ l r ) 2 x n − 2 = . . . = ( 1 − 2 ∗ l r ) n x 0 x_n = (1 - 2 * lr)x_{n-1} = (1 - 2 * lr)^2 x_{n-2} = ... = (1 - 2 * lr)^{n}x_0 xn=(12lr)xn1=(12lr)2xn2=...=(12lr)nx0

由上述式子可以看出,因为 1 − 2 ∗ l r < 0 1 - 2 * lr < 0 12lr<0,所以当 1 − 2 ∗ l r < − 1 1 - 2 * lr < -1 12lr<1 l r > 1 lr > 1 lr>1 时,几个迭代后梯度将会出现爆炸的情况。


设 损失函数 L L L ω 0 \omega_0 ω0 处的梯度为
g ( ω 0 ) = ∂ L ∂ ω 0 g(\omega_0) = \frac{\partial{L}}{\partial{\omega_0}} g(ω0)=ω0L

更新后
ω 1 = ω 0 − l ∗ g ( ω 0 ) \omega_1=\omega_0 - l*g(\omega_0) ω1=ω0lg(ω0)

继续上述过程,可以得到
ω 2 = ω 1 − l ∗ g ( ω 1 ) = ω 0 − l ∗ g ( ω 0 ) − l ∗ g ( ω 1 ) = ω 0 − l ∗ g ( ω 0 ) − l ∗ g ( ω 1 ) = ω 0 − l ∑ i = 0 1 g ( ω i ) \begin{aligned} \omega_2 &= \omega_1 - l * g(\omega_1) \\ &=\omega_0 - l*g(\omega_0)-l*g(\omega_1) \\&= \omega_0 - l*g(\omega_0)-l*g(\omega_1) \\&=\omega_0 -l\sum_{i=0}^{1} g(\omega_i) \end{aligned} ω2=ω1lg(ω1)=ω0lg(ω0)lg(ω1)=ω0lg(ω0)lg(ω1)=ω0li=01g(ωi)

所以
ω n = ω 0 − l ∑ i = 0 n − 1 g ( ω i ) \omega_n = \omega_0 -l\sum_{i=0}^{n-1} g(\omega_i) ωn=ω0li=0n1g(ωi)

n n n 次的权重值 ω n \omega_n ωn,由权重初始值 ω 0 \omega_0 ω0 和前 n − 1 n-1 n1 次的梯度之和确定。当梯度稳定变小时,表明损失函数接近最优值,越接近最优值时,梯度 g ( ω i ) g(\omega_i) g(ωi) 趋近于 0 0 0,此时 ω n \omega_n ωn 将几乎不再变化,函数收敛。

如上图所示,梯度 grad 由 损失函数 Loss 确定,损失函数越大时,梯度也越大。待优化参数 ω \omega ω 由梯度 grad 和 学习率 lr 共同确定,参数更新后,损失函数也将缩小,从而进一步缩小梯度,直到损失函数最小,梯度为 0,此时得到最优解。如果参数 ω \omega ω 更新后,损失函数不但没有缩小,反而增大,此时将进一步增大梯度,最终造成梯度爆炸。

以下是使用PSO优化卷积神经网络的学习率损失函数系数的例子: 1. 首先,定义一个卷积神经网络模型,并且需要训练的参数包括学习率损失函数系数。例如: ``` class CNN(nn.Module): def __init__(self, learning_rate, loss_coeff): super(CNN, self).__init__() self.conv1 = nn.Conv2d(3, 32, 3, padding=1) self.conv2 = nn.Conv2d(32, 64, 3, padding=1) self.fc1 = nn.Linear(64 * 8 * 8, 500) self.fc2 = nn.Linear(500, 10) self.learning_rate = learning_rate self.loss_coeff = loss_coeff def forward(self, x): x = F.relu(self.conv1(x)) x = F.max_pool2d(x, 2) x = F.relu(self.conv2(x)) x = F.max_pool2d(x, 2) x = x.view(-1, 64 * 8 * 8) x = F.relu(self.fc1(x)) x = self.fc2(x) return x ``` 2. 然后,定义一个PSO优化器,用于优化学习率损失函数系数。例如: ``` class PSOOptimizer: def __init__(self, num_particles, c1, c2, w_min, w_max, num_epochs): self.num_particles = num_particles self.c1 = c1 self.c2 = c2 self.w_min = w_min self.w_max = w_max self.num_epochs = num_epochs def optimize(self, cnn): best_loss = float('inf') best_lr = cnn.learning_rate best_coeff = cnn.loss_coeff num_params = len(list(cnn.parameters())) particles = np.zeros((self.num_particles, num_params * 2)) velocities = np.zeros((self.num_particles, num_params * 2)) for i in range(self.num_particles): lr = np.random.uniform(0.001, 0.01) coeff = np.random.uniform(0.5, 1.0) particles[i,:] = np.concatenate((np.repeat(lr, num_params), np.repeat(coeff, num_params))) for epoch in range(self.num_epochs): for i in range(self.num_particles): cnn.learning_rate = particles[i,:num_params].reshape(-1,1) cnn.loss_coeff = particles[i,num_params:].reshape(-1,1) optimizer = optim.SGD(cnn.parameters(), lr=cnn.learning_rate, momentum=0.9) criterion = nn.CrossEntropyLoss(weight=torch.Tensor([cnn.loss_coeff]*10)) train_loss = train(cnn, optimizer, criterion) if train_loss < best_loss: best_loss = train_loss best_lr = cnn.learning_rate best_coeff = cnn.loss_coeff r1 = np.random.rand(num_params * 2) r2 = np.random.rand(num_params * 2) velocities[i] = self.w_max * (velocities[i] + self.c1 * r1 * (particles[i] - particles[i]) + self.c2 * r2 * (best_loss - particles[i])) velocities[i][velocities[i] < self.w_min] = self.w_min velocities[i][velocities[i] > self.w_max] = self.w_max particles[i] += velocities[i] particles[i][particles[i] < 0] = 0 particles[i][particles[i] > 1] = 1 cnn.learning_rate = best_lr cnn.loss_coeff = best_coeff return cnn ``` 3. 最后,定义一个训练函数,用于训练卷积神经网络,并返回训练损失。例如: ``` def train(cnn, optimizer, criterion): train_loss = 0.0 for batch_idx, (data, target) in enumerate(train_loader): optimizer.zero_grad() output = cnn(data) loss = criterion(output, target) loss.backward() optimizer.step() train_loss += loss.item() * len(data) train_loss /= len(train_loader.dataset) return train_loss ``` 通过以上三个步骤,我们可以使用PSO优化学习率损失函数系数来训练卷积神经网络。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值