PyTorch教程(九):损失函数与Loss的梯度
均方差Mean Squared Error(MSE)
MSE基本形式:
loss=∑[y?(xw+b)]2loss = \sum[y-(xw+b)]^2 loss=∑[y?(xw+b)]2
這里的模型使用非常簡單的線性感知機,如果使用其他的網(wǎng)絡,則修改為loss=∑[y?f(x;w,b)]2loss = \sum[y-f(x;w,b)]^2loss=∑[y?f(x;w,b)]2
需要注意的是,這里的均方差MSE和L2-norm是有區(qū)別的:
l2?norm=∑(y1?y2)2l2-norm=\sqrt{\sum{(y_1-y_2)^2}} l2?norm=∑(y1??y2?)2?
PyTorch在MSE中的使用:torch.norm(y-y',2).pow(2)
MSE梯度
loss=∑[y?fθ(x)]2?loss?θ=2∑[y?fθ(x)]??fθ(x)?θloss = \sum[y-f_\theta(x)]^2 \\ \frac{\nabla loss}{\nabla \theta} = 2\sum[y-f_\theta(x)]*\frac{\nabla f_\theta(x)}{\nabla \theta} loss=∑[y?fθ?(x)]2?θ?loss?=2∑[y?fθ?(x)]??θ?fθ?(x)?
因此,如果使用簡單的線性回歸,那么f(x)=wx+bf(x)=wx+bf(x)=wx+b,那么對于?fθ(x)?θ\frac{\nabla f_\theta(x)}{\nabla \theta}?θ?fθ?(x)?則為(x,1)
使用torch.autograd.grad(loss,[w1,w2…])求導
返回結果是list的方式:[w1 grad, w2 grad, w3 grad .....]
這里使用最簡單的線性模型y=wxy=wxy=wx
loss=(1?1?2)2?loss?w=2?(1?2)?(?1)?loss?w=2loss = (1-1*2)^2 \\ \frac{\partial loss}{\partial w} = 2 * (1-2)*(-1)\frac{\partial loss}{\partial w} = 2 loss=(1?1?2)2?w?loss?=2?(1?2)?(?1)?w?loss?=2
設置w的梯度還可以通過在初始化時進行設置,w = torch.tensor([1],requires_grad=True)
使用loss.backward()求導
不會額外返回結果,而是直接附加在每個成員變量上,結果是:w1.grad,w2.grad…
除了使用torch.autograd.grad(mse,[w])方式求導外,還可以使用:
mse.backward()表示向后傳播,PyTorch會自動記錄下圖的路徑,因此在最后的loss節(jié)點上調(diào)用backward時,會完成這條路徑上所有的需要梯度grad的計算,這個計算后的grad不會直接返回,而是會自動把grad信息附加在每個tensor的成員變量.grad上,因為這個只有一個w參數(shù),因此只有一個w.grad,
Cross Entropy Loss
常見的分類中的損失函數(shù),既可以用于二分類,也可以用多分類,一般跟softmax激活函數(shù)搭配一起使用。
softmax激活函數(shù)
對于一個輸出y,如果需要轉為概率值,希望概率最大的值作為預測的label,如上圖,2.0最大,其對應的索引是0,因此0就是一個label。但是我們的概率是屬于一個區(qū)間,如果要把這個值轉為概率值,需要人為進行壓縮,可以使用sigmoid函數(shù)來完成,但是對于多分類來說,一個物體到底屬于哪個類,有概率的大小之分,而這些概率之和為1。因此使用sigmoid并不是十分準確。
對于softmax的屬性是:每一個值的大小范圍是(0,1),所有概率之和為1。
S(yi)=eyi∑jeyjS(y_i) = \frac{e^{y_i}}{\sum_je^{y_j}} S(yi?)=∑j?eyj?eyi??
對于上面的例子:
e2e2+e1+e0.1+e1e2+e1+e0.1+e0.1e2+e1+e0.1=1\frac{e^2}{e^2+e^1+e0.1}+\frac{e^1}{e^2+e^1+e0.1}+\frac{e^{0.1}}{e^2+e^1+e0.1} = 1 e2+e1+e0.1e2?+e2+e1+e0.1e1?+e2+e1+e0.1e0.1?=1
之前的標簽2和1的差距只有2倍,而經(jīng)過softmax操作之后,0.7和0.2的差距卻放大了。因此softmax會將原來的差距拉大。
softmax導數(shù)
pi=eai∑k=1Neak?pi?aj={pi(1?pj)if?i?=?j?pj?pi,if?i≠jp_i = \frac{e^{a_i}}{\sum_{k=1}^Ne^{a_k}} \\ \frac{\partial p_i}{\partial a_j} = \begin{cases} p_i(1-p_j) & \text {if i = j} \\ -p_j·p_i, & \text{if i}\ne j \end{cases} pi?=∑k=1N?eak?eai???aj??pi??={pi?(1?pj?)?pj??pi?,?if?i?=?jif?i?=j?
可以根據(jù)公式看出當i=j時,梯度是大于0的,其他情況下是小于0的。
計算梯度
a = torch.rand(3) a.requires_grad_() # tensor([0.2306, 0.6693, 0.6334], requires_grad=True)p = F.softmax(a, dim=0) # tensor([0.2471, 0.3832, 0.3697], grad_fn=<SoftmaxBackward>) torch.autograd.grad(p[0],[a], retain_graph=True) # (tensor([ 0.1860, -0.0947, -0.0914]),) torch.autograd.grad(p[1],[a], retain_graph=True) # (tensor([-0.0947, 0.2364, -0.1417]),) torch.autograd.grad(p[2],[a], retain_graph=True) # (tensor([-0.0914, -0.1417, 0.2330]),)?p0?ai=[0.1860,?0.0947,?0.0914]\frac{\partial p_0}{\partial a_i}=[ 0.1860, -0.0947, -0.0914]?ai??p0??=[0.1860,?0.0947,?0.0914],其中?p0?a0=[0.1860],?p0?a1=[?0.0947],?p0?a2=[?0.0914]\frac{\partial p_0}{\partial a_0}=[ 0.1860],\frac{\partial p_0}{\partial a_1}=[ -0.0947],\frac{\partial p_0}{\partial a_2}=[ -0.0914]?a0??p0??=[0.1860],?a1??p0??=[?0.0947],?a2??p0??=[?0.0914]可以看出當j=i時,梯度信息是正的。
總結
以上是生活随笔為你收集整理的PyTorch教程(九):损失函数与Loss的梯度的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 打金传奇哪个靠谱(可以赚人民币的传奇手游
- 下一篇: 延禧攻略什么时候播(延禧攻略定档7月19