@飛槳深度學習架構師訓練營-在學習過程中的幾點疑問
csdn不能上傳自己寫的md嗎?簡單的手敲一遍做個總結。
列舉了一些在初次看代碼時比較疑惑的地方,以及目前對該問題的了解。
一、眼疾資料集分類的訓練過程
1.代碼
import os
import random
import paddle
import paddle.fluid as fluid
import numpy as np
DATADIR = '/home/aistudio/work/palm/PALM-Training400/PALM-Training400'
DATADIR2 = '/home/aistudio/work/palm/PALM-Validation400'
CSVFILE = '/home/aistudio/labels.csv'
# 定義訓練過程
def train(model):
with fluid.dygraph.guard():
print('start training ... ')
model.train()
epoch_num = 1
# 定義優化器
opt = fluid.optimizer.Momentum(learning_rate=0.001, momentum=0.9, parameter_list=model.parameters())
# 定義資料讀取器,訓練資料讀取器和驗證資料讀取器
train_loader = data_loader(DATADIR, batch_size=10, mode='train')
valid_loader = valid_data_loader(DATADIR2, CSVFILE)
for epoch in range(epoch_num):
for batch_id, data in enumerate(train_loader()):
x_data, y_data = data
img = fluid.dygraph.to_variable(x_data)
label = fluid.dygraph.to_variable(y_data)
# 運作模型前向計算,得到預測值
logits = model(img)
# 進行loss計算
loss = fluid.layers.sigmoid_cross_entropy_with_logits(logits, label)
avg_loss = fluid.layers.mean(loss)
if batch_id % 10 == 0:
print("epoch: {}, batch_id: {}, loss is: {}".format(epoch, batch_id, avg_loss.numpy()))
# 反向傳播,更新權重,清除梯度
avg_loss.backward()
opt.minimize(avg_loss)
model.clear_gradients()
model.eval()
accuracies = []
losses = []
for batch_id, data in enumerate(valid_loader()):
x_data, y_data = data
img = fluid.dygraph.to_variable(x_data)
label = fluid.dygraph.to_variable(y_data)
# 運作模型前向計算,得到預測值
logits = model(img)
# 二分類,sigmoid計算後的結果以0.5為門檻值分兩個類别
# 計算sigmoid後的預測機率,進行loss計算
pred = fluid.layers.sigmoid(logits)
loss = fluid.layers.sigmoid_cross_entropy_with_logits(logits, label)
# 計算預測機率小于0.5的類别
pred2 = pred * (-1.0) + 1.0
# 得到兩個類别的預測機率,并沿第一個次元級聯
pred = fluid.layers.concat([pred2, pred], axis=1)
print('pred', pred)
acc = fluid.layers.accuracy(pred, fluid.layers.cast(label, dtype='int64'))
accuracies.append(acc.numpy())
losses.append(loss.numpy())
print("[validation] accuracy/loss: {}/{}".format(np.mean(accuracies), np.mean(losses)))
model.train()
# save params of model
fluid.save_dygraph(model.state_dict(), 'palm')
# save optimizer state
fluid.save_dygraph(opt.state_dict(), 'palm')
2.疑問
(1)前向計算的結果logits,傳入sigmod之後,得到一個分類機率pred,這個機率是屬于正樣本的機率,還是屬于負樣本的機率?如果pred特指正樣本,那為什麼前向計算的結果,一定是屬于正樣本的機率呢?
pred歸屬于哪個樣本,取決于它對應的label。假設它的label是0,pred是0.55,說明它有55%的機率屬于負樣本。也就是說pred在和label聯系起來之前并沒有特指某個種類。
(2)sigmod和softmax
sigmod和softmax都可用于分類問題。
1)sigmod
sigmod能把輸入值轉換到0~1之間。
sigmod公式:
y = 1 1 + e − x y=\frac{1}{1+e^{-x}} y=1+e−x1
也有的資料說是下面的這個:
y = e − x 1 + e − x y=\frac{e^{-x}}{1+e^{-x}} y=1+e−xe−x
sigmod曲線趨勢

2)softmax
softmax的輸出資料之間存在關聯,和為1.
softmax公式
softmax層
3)二分類問題
在二分類問題上,當得出了其中一種可能的機率p1時,就可以推知另一種可能p2的機率 p 1 = 1 − p 2 p_1=1-p_2 p1=1−p2
是以在二分類問題上可以用sigmod代替softmax,二者在數學上是等價的(這裡沒想明白,這倆數值上也不相等呀,隻能了解為,兩者都可以算機率,用哪一種都行)。
還有部分還沒消化,以後補充
二、關于學習深度學習模型的幾點疑問
1.學習一個新的模型時,比如yolov3這種代碼結構比較複雜的模型,是應該深究每一層網絡的處理流程(會耗費大量時間),還是隻需要弄清楚,每一層網絡輸出的資料的格式呢?
2.看yolov3的時候,經常會疑惑,這麼複雜的網絡是怎麼想出來的呢?是嘗試着去一層一層湊出來的?為什麼會需要這麼多的卷積層?
3.飛槳的封裝做得很好,在搭建網絡時,直接調用想要的網絡結構即可,不需要自己去編寫特定層的網絡結構。
作為深度學習的初學者,有必要每一層網絡都自己親手一層一層搭建嗎(搭建網絡比較耗時)?還是說,把代碼當成能驗證猜想的工具,重點應該放在理論上,可是,不清楚每一層的具體結構,或者說資料到了這一層會發生什麼樣的變化,怎麼在網絡結構上做合理的更改呢?
4.在碩士階段,周圍的人研究深度學習的時候,大緻路線有幾種:
(1)找一個完善的模型去适應特定的場景;
(2)找一個完善的模型,在網絡結構上增删改;
如果效果很好,就算找到創新點,可以發論文了。這真的算創新嗎?有點像野豬蒙着眼睛撞樹,撞斷哪顆算哪顆,直到撞出一條新路,運氣好的就不用頭破血流。我以為的創新,不是簡單的縫縫補補,在前人的基礎上做一點微小的修改,而是整個體系上的變更。我知道很難,但是這不才是做研究應該有的樣子嗎?我的研究路線還沒确定,很疑惑,是不是應該先按着周圍人的路線去嘗試。