NNDL实验五 前馈神经网络(2)自动梯度计算 优化问题
4.3 自動梯度計算
雖然我們能夠通過模塊化的方式比較好地對神經(jīng)網(wǎng)絡(luò)進(jìn)行組裝,但是每個模塊的梯度計算過程仍然十分繁瑣且容易出錯。在深度學(xué)習(xí)框架中,已經(jīng)封裝了自動梯度計算的功能,我們只需要聚焦模型架構(gòu),不再需要耗費(fèi)精力進(jìn)行計算梯度。
飛槳提供了paddle.nn.Layer類,來方便快速的實(shí)現(xiàn)自己的層和模型。模型和層都可以基于paddle.nn.Layer擴(kuò)充實(shí)現(xiàn),模型只是一種特殊的層。繼承了paddle.nn.Layer類的算子中,可以在內(nèi)部直接調(diào)用其它繼承paddle.nn.Layer類的算子,飛槳框架會自動識別算子中內(nèi)嵌的paddle.nn.Layer類算子,并自動計算它們的梯度,并在優(yōu)化時更新它們的參數(shù)。
4.3.1 利用預(yù)定義算子重新實(shí)現(xiàn)前饋神經(jīng)網(wǎng)絡(luò)
1. 使用pytorch的預(yù)定義算子來重新實(shí)現(xiàn)二分類任務(wù)。(必做)
主要使用到的預(yù)定義算子為torch.nn.Linear
CLASS torch.nn.Linear(in_features, out_features, bias=True, device=None, dtype=None)
torch.nn.Linear算子可以接受一個形狀為[,]的輸入張量,其中""表示張量中可以有任意的其它額外維度,并計算它與形狀為[out_features, in_features]的權(quán)重矩陣的乘積,然后生成形狀為[,]的輸出張量。 torch.nn.Linear算子默認(rèn)有偏置參數(shù),可以通過bias=False設(shè)置不帶偏置。
代碼實(shí)現(xiàn):
2. 增加一個3個神經(jīng)元的隱藏層,再次實(shí)現(xiàn)二分類,并與1做對比。(必做)
4.3.2 完善Runner類
?基于上一節(jié)實(shí)現(xiàn)的?RunnerV2_1?類,本節(jié)的?RunnerV2_2類在訓(xùn)練過程中使用自動梯度計算;模型保存時,使用state_dict方法獲取模型參數(shù);模型加載時,使用set_state_dict方法加載模型參數(shù).
代碼實(shí)現(xiàn)如下:
#完善Runner類 class RunnerV2_2(object):def __init__(self, model, optimizer, metric, loss_fn, **kwargs):self.model = modelself.optimizer = optimizerself.loss_fn = loss_fnself.metric = metric# 記錄訓(xùn)練過程中的評估指標(biāo)變化情況self.train_scores = []self.dev_scores = []# 記錄訓(xùn)練過程中的評價指標(biāo)變化情況self.train_loss = []self.dev_loss = []def train(self, train_set, dev_set, **kwargs):# 將模型切換為訓(xùn)練模式self.model.train()# 傳入訓(xùn)練輪數(shù),如果沒有傳入值則默認(rèn)為0num_epochs = kwargs.get("num_epochs", 0)# 傳入log打印頻率,如果沒有傳入值則默認(rèn)為100log_epochs = kwargs.get("log_epochs", 100)# 傳入模型保存路徑,如果沒有傳入值則默認(rèn)為"best_model.pdparams"save_path = kwargs.get("save_path", "best_model.pdparams")# log打印函數(shù),如果沒有傳入則默認(rèn)為"None"custom_print_log = kwargs.get("custom_print_log", None)# 記錄全局最優(yōu)指標(biāo)best_score = 0# 進(jìn)行num_epochs輪訓(xùn)練for epoch in range(num_epochs):X, y = train_set# 獲取模型預(yù)測logits = self.model(X)# 計算交叉熵?fù)p失trn_loss = self.loss_fn(logits, y)self.train_loss.append(trn_loss.item())# 計算評估指標(biāo)trn_score = self.metric(logits, y).item()self.train_scores.append(trn_score)# 自動計算參數(shù)梯度trn_loss.backward()if custom_print_log is not None:# 打印每一層的梯度custom_print_log(self)# 參數(shù)更新self.optimizer.step()# 清空梯度self.optimizer.zero_grad()dev_score, dev_loss = self.evaluate(dev_set)# 如果當(dāng)前指標(biāo)為最優(yōu)指標(biāo),保存該模型if dev_score > best_score:self.save_model(save_path)print(f"[Evaluate] best accuracy performence has been updated: {best_score:.5f} --> {dev_score:.5f}")best_score = dev_scoreif log_epochs and epoch % log_epochs == 0:print(f"[Train] epoch: {epoch}/{num_epochs}, loss: {trn_loss.item()}")# 模型評估階段,使用'torch.no_grad()'控制不計算和存儲梯度@torch.no_grad()def evaluate(self, data_set):# 將模型切換為評估模式self.model.eval()X, y = data_set# 計算模型輸出logits = self.model(X)# 計算損失函數(shù)loss = self.loss_fn(logits, y).item()self.dev_loss.append(loss)# 計算評估指標(biāo)score = self.metric(logits, y).item()self.dev_scores.append(score)return score, loss# 模型測試階段,使用'torch.no_grad()'控制不計算和存儲梯度@torch.no_grad()def predict(self, X):# 將模型切換為評估模式self.model.eval()return self.model(X)# 使用'model.state_dict()'獲取模型參數(shù),并進(jìn)行保存def save_model(self, saved_path):torch.save(self.model.state_dict(), saved_path)# 使用'model.set_state_dict'加載模型參數(shù)def load_model(self, model_path):state_dict = torch.load(model_path)self.model.set_state_dict(state_dict)?4.3.3 模型訓(xùn)練
實(shí)例化RunnerV2類,并傳入訓(xùn)練配置
代碼實(shí)現(xiàn):
from nndl.metric import accuracy input_size = 2 hidden_size = 5 output_size = 1 model = Model_MLP_L2_V2(input_size=input_size, hidden_size=hidden_size, output_size=output_size)# 設(shè)置損失函數(shù) loss_fn = F.binary_cross_entropy# 設(shè)置優(yōu)化器 learning_rate = 0.2 optimizer = torch.optim.SGD(model.parameters(), learning_rate)# 設(shè)置評價指標(biāo) metric = accuracy# 其他參數(shù) epoch_num = 1000 saved_path = 'best_model.pdparams'# 實(shí)例化RunnerV2類,并傳入訓(xùn)練配置 runner = RunnerV2_2(model, optimizer, metric, loss_fn)runner.train([X_train, y_train], [X_dev, y_dev], num_epochs=epoch_num, log_epochs=50, save_path="best_model.pdparams")??將訓(xùn)練過程中訓(xùn)練集與驗(yàn)證集的準(zhǔn)確率變化情況進(jìn)行可視化。
# 可視化觀察訓(xùn)練集與驗(yàn)證集的指標(biāo)變化情況import matplotlib.pyplot as plt def plot(runner, fig_name):plt.figure(figsize=(10, 5))epochs = [i for i in range(len(runner.train_scores))]plt.subplot(1, 2, 1)plt.plot(epochs, runner.train_loss, color='#e4007f', label="Train loss")plt.plot(epochs, runner.dev_loss, color='#f19ec2', linestyle='--', label="Dev loss")# 繪制坐標(biāo)軸和圖例plt.ylabel("loss", fontsize='large')plt.xlabel("epoch", fontsize='large')plt.legend(loc='upper right', fontsize='x-large')plt.subplot(1, 2, 2)plt.plot(epochs, runner.train_scores, color='#e4007f', label="Train accuracy")plt.plot(epochs, runner.dev_scores, color='#f19ec2', linestyle='--', label="Dev accuracy")# 繪制坐標(biāo)軸和圖例plt.ylabel("score", fontsize='large')plt.xlabel("epoch", fontsize='large')plt.legend(loc='lower right', fontsize='x-large')plt.savefig(fig_name)plt.show()plot(runner, 'fw-acc.pdf')?
4.3.4 性能評價
?使用測試數(shù)據(jù)對訓(xùn)練完成后的最優(yōu)模型進(jìn)行評價,觀察模型在測試集上的準(zhǔn)確率以及l(fā)oss情況。代碼如下:
#性能評價 # 模型評價 score, loss = runner.evaluate([X_test, y_test]) print("[Test] score/loss: {:.4f}/{:.4f}".format(score, loss))?
從結(jié)果來看,模型在測試集上取得了較高的準(zhǔn)確率。
增加一個3個神經(jīng)元的隱藏層,再次實(shí)現(xiàn)二分類,并與1做對比。
其中模型定義代碼修改為:
class Model_MLP_L2_V4(nn.Module):def __init__(self, input_size, hidden_size, hidden_size_3, output_size):super(Model_MLP_L2_V4, self).__init__()self.fc1 = nn.Linear(input_size, hidden_size)normal_(self.fc1.weight, mean=0., std=1.)constant_(self.fc1.bias, val=0.0)self.fc2 = nn.Linear(hidden_size, hidden_size_3)normal_(self.fc2.weight, mean=0., std=1.)constant_(self.fc2.bias, val=0.0)self.fc3 = nn.Linear(hidden_size_3, output_size)normal_(self.fc3.weight, mean=0., std=1.)constant_(self.fc3.bias, val=0.0)self.act_fn = torch.sigmoid# 前向計算def forward(self, inputs):z1 = self.fc1(inputs.to(torch.float32))a1 = self.act_fn(z1)z2 = self.fc2(a1)a2 = self.act_fn(z2)z3 = self.fc3(a2)a3 = self.act_fn(z3)return a3?模型的訓(xùn)練修改:
# 設(shè)置模型 input_size = 2 hidden_size = 5 hidden_size_3 = 3 output_size = 1 model = Model_MLP_L2_V4(input_size=input_size, hidden_size=hidden_size, hidden_size_3=3, output_size=output_size)# 設(shè)置損失函數(shù) loss_fn = F.binary_cross_entropy# 設(shè)置優(yōu)化器 learning_rate = 0.2 optimizer = torch.optim.SGD(model.parameters(), learning_rate)# 設(shè)置評價指標(biāo) metric = accuracy# 其他參數(shù) epoch_num = 1000 saved_path = 'best_model.pdparams'# 實(shí)例化RunnerV2類,并傳入訓(xùn)練配置 runner = RunnerV2_2(model, optimizer, metric, loss_fn) runner.train([X_train, y_train], [X_dev, y_dev], num_epochs=epoch_num, log_epochs=50, save_path="best_model.pdparams")運(yùn)行結(jié)果:
?
可視化結(jié)果:
模型評價:
通過這兩個實(shí)驗(yàn)結(jié)果的對比可以明顯的看出,在增加了一層隱藏神經(jīng)元后,誤差和學(xué)習(xí)率有了明顯提升。
【思考題】
自定義梯度計算和自動梯度計算:
自定義梯度計算:是利用公式手動推導(dǎo)出相應(yīng)的表達(dá)式,然后再將其寫到程序中去,并實(shí)現(xiàn)計算。
自動梯度計算:是利用torch中的相應(yīng)的已經(jīng)定義好的函數(shù)根據(jù)鏈?zhǔn)椒▌t求導(dǎo),計算結(jié)果。
自動梯度計算不管從時間還是結(jié)果上都要優(yōu)于自定義梯度計算。
4.4 優(yōu)化問題
在本節(jié)中,我們通過實(shí)踐來發(fā)現(xiàn)神經(jīng)網(wǎng)絡(luò)模型的優(yōu)化問題,并思考如何改進(jìn)。
4.4.1 參數(shù)初始化
實(shí)現(xiàn)一個神經(jīng)網(wǎng)絡(luò)前,需要先初始化模型參數(shù)。
如果對每一層的權(quán)重和偏置都用0初始化,那么通過第一遍前向計算,所有隱藏層神經(jīng)元的激活值都相同;在反向傳播時,所有權(quán)重的更新也都相同,這樣會導(dǎo)致隱藏層神經(jīng)元沒有差異性,出現(xiàn)對稱權(quán)重現(xiàn)象。
接下來,將模型參數(shù)全都初始化為0,看實(shí)驗(yàn)結(jié)果。這里重新定義了一個類,兩個線性層的參數(shù)全都初始化為0
?
?
def print_weights(runner):print('The weights of the Layers:')for item in runner.model.named_parameters():print(item)利用Runner類訓(xùn)練模型:
# 設(shè)置模型 input_size = 2 hidden_size = 5 output_size = 1 model = Model_MLP_L2_V4(input_size=input_size, hidden_size=hidden_size, output_size=output_size)# 設(shè)置損失函數(shù) loss_fn = F.binary_cross_entropy# 設(shè)置優(yōu)化器 learning_rate = 0.2 # 5e-2 optimizer = torch.optim.SGD(model.parameters(), learning_rate)# 設(shè)置評價指標(biāo) metric = accuracy# 其他參數(shù) epoch = 2000 saved_path = 'best_model.pdparams'# 實(shí)例化RunnerV2類,并傳入訓(xùn)練配置 runner = RunnerV2_2(model, optimizer, metric, loss_fn) runner.train([X_train, y_train], [X_dev, y_dev], num_epochs=5, log_epochs=50, save_path="best_model.pdparams", custom_print_log=print_weights)?
?可視化訓(xùn)練和驗(yàn)證集上的主準(zhǔn)確率和loss變化:?
def plot(runner, fig_name):plt.figure(figsize=(10, 5))epochs = [i for i in range(len(runner.train_scores))]plt.subplot(1, 2, 1)plt.plot(epochs, runner.train_loss, color='#e4007f', label="Train loss")plt.plot(epochs, runner.dev_loss, color='#f19ec2', linestyle='--', label="Dev loss")# 繪制坐標(biāo)軸和圖例plt.ylabel("loss", fontsize='large')plt.xlabel("epoch", fontsize='large')plt.legend(loc='upper right', fontsize='x-large')plt.subplot(1, 2, 2)plt.plot(epochs, runner.train_scores, color='#e4007f', label="Train accuracy")plt.plot(epochs, runner.dev_scores, color='#f19ec2', linestyle='--', label="Dev accuracy")# 繪制坐標(biāo)軸和圖例plt.ylabel("score", fontsize='large')plt.xlabel("epoch", fontsize='large')plt.legend(loc='lower right', fontsize='x-large')plt.savefig(fig_name)plt.show()plot(runner, "fw-zero.pdf")?從輸出結(jié)果看,二分類準(zhǔn)確率為50%左右,說明模型沒有學(xué)到任何內(nèi)容。訓(xùn)練和驗(yàn)證loss幾乎沒有怎么下降。
為了避免對稱權(quán)重現(xiàn)象,可以使用高斯分布或均勻分布初始化神經(jīng)網(wǎng)絡(luò)的參數(shù)。
高斯分布和均勻分布采樣的實(shí)現(xiàn)和可視化代碼如下:
gausian_weights = torch.normal(mean=0.0, std=1.0, size=[10000]) uniform_weights = torch.Tensor(10000) uniform_weights.uniform_(-1, 1) # 繪制兩種參數(shù)分布 plt.figure() plt.subplot(1, 2, 1) plt.title('Gausian Distribution') plt.hist(gausian_weights, bins=200, density=True, color='#f19ec2') plt.subplot(1, 2, 2) plt.title('Uniform Distribution') plt.hist(uniform_weights, bins=200, density=True, color='#e4007f') plt.savefig('fw-gausian-uniform.pdf') plt.show()?
4.4.2 梯度消失問題
在神經(jīng)網(wǎng)絡(luò)的構(gòu)建過程中,隨著網(wǎng)絡(luò)層數(shù)的增加,理論上網(wǎng)絡(luò)的擬合能力也應(yīng)該是越來越好的。但是隨著網(wǎng)絡(luò)變深,參數(shù)學(xué)習(xí)更加困難,容易出現(xiàn)梯度消失問題。
由于Sigmoid型函數(shù)的飽和性,飽和區(qū)的導(dǎo)數(shù)更接近于0,誤差經(jīng)過每一層傳遞都會不斷衰減。當(dāng)網(wǎng)絡(luò)層數(shù)很深時,梯度就會不停衰減,甚至消失,使得整個網(wǎng)絡(luò)很難訓(xùn)練,這就是所謂的梯度消失問題。
在深度神經(jīng)網(wǎng)絡(luò)中,減輕梯度消失問題的方法有很多種,一種簡單有效的方式就是使用導(dǎo)數(shù)比較大的激活函數(shù),如:ReLU。
下面通過一個簡單的實(shí)驗(yàn)觀察前饋神經(jīng)網(wǎng)絡(luò)的梯度消失現(xiàn)象和改進(jìn)方法。
4.4.2.1 模型構(gòu)建
定義一個前饋神經(jīng)網(wǎng)絡(luò),包含4個隱藏層和1個輸出層,通過傳入的參數(shù)指定激活函數(shù)。代碼實(shí)現(xiàn)如下:
?
?
4.4.2.2 使用Sigmoid型函數(shù)進(jìn)行訓(xùn)練
使用Sigmoid型函數(shù)作為激活函數(shù),為了便于觀察梯度消失現(xiàn)象,只進(jìn)行一輪網(wǎng)絡(luò)優(yōu)化。代碼實(shí)現(xiàn)如下:
定義梯度打印函數(shù)
def print_grads(runner):# 打印每一層的權(quán)重的模print('The gradient of the Layers:')for name, item in runner.model.named_parameters():if len(item.size()) == 2:print(name, torch.norm(input=item, p=2)) # 學(xué)習(xí)率大小 lr = 0.01 # 定義網(wǎng)絡(luò),激活函數(shù)使用sigmoid model = Model_MLP_L5(input_size=2, output_size=1, act='sigmoid') # 定義優(yōu)化器 optimizer = torch.optim.SGD(lr=lr, params=model.parameters()) # 定義損失函數(shù),使用交叉熵?fù)p失函數(shù) loss_fn = F.binary_cross_entropy # 定義評價指標(biāo) metric = accuracy # 指定梯度打印函數(shù) custom_print_log=print_grads # 實(shí)例化Runner類 runner = RunnerV2_2(model, optimizer, metric, loss_fn) # 啟動訓(xùn)練 runner.train([X_train, y_train], [X_dev, y_dev], num_epochs=1, log_epochs=None, save_path="best_model.pdparams", custom_print_log=custom_print_log)實(shí)例化RunnerV2_2類,并傳入訓(xùn)練配置。代碼實(shí)現(xiàn)如下:
# 實(shí)例化Runner類 runner = RunnerV2_2(model, optimizer, metric, loss_fn)?模型訓(xùn)練,打印網(wǎng)絡(luò)每層梯度值的?2范數(shù)。代碼實(shí)現(xiàn)如下:
# 啟動訓(xùn)練 runner.train([X_train, y_train], [X_dev, y_dev], num_epochs=1, log_epochs=None, save_path="best_model.pdparams", custom_print_log=custom_print_log)運(yùn)行結(jié)果:
觀察實(shí)驗(yàn)結(jié)果可以發(fā)現(xiàn),梯度經(jīng)過每一個神經(jīng)層的傳遞都會不斷衰減,最終傳遞到第一個神經(jīng)層時,梯度幾乎完全消失。
4.4.2.3 使用ReLU函數(shù)進(jìn)行模型訓(xùn)練
torch.manual_seed(102) lr = 0.01 # 學(xué)習(xí)率大小 # 定義網(wǎng)絡(luò),激活函數(shù)使用relu model = Model_MLP_L5(input_size=2, output_size=1, act='relu') # 定義優(yōu)化器 optimizer = torch.optim.SGD(lr=lr, params=model.parameters()) # 定義損失函數(shù) # 定義損失函數(shù),這里使用交叉熵?fù)p失函數(shù) loss_fn = F.binary_cross_entropy # 定義評估指標(biāo) metric = accuracy # 實(shí)例化Runner runner = RunnerV2_2(model, optimizer, metric, loss_fn) # 啟動訓(xùn)練 runner.train([X_train, y_train], [X_dev, y_dev], num_epochs=1, log_epochs=None, save_path="best_model.pdparams", custom_print_log=custom_print_log)?下圖展示了使用不同激活函數(shù)時,網(wǎng)絡(luò)每層梯度值的?2?2范數(shù)情況。從結(jié)果可以看到,5層的全連接前饋神經(jīng)網(wǎng)絡(luò)使用Sigmoid型函數(shù)作為激活函數(shù)時,梯度經(jīng)過每一個神經(jīng)層的傳遞都會不斷衰減,最終傳遞到第一個神經(jīng)層時,梯度幾乎完全消失。改為ReLU激活函數(shù)后,梯度消失現(xiàn)象得到了緩解,每一層的參數(shù)都具有梯度值。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 網(wǎng)絡(luò)每層梯度的L2范數(shù)變化趨勢
4.4.3 死亡ReLU問題
ReLU激活函數(shù)可以一定程度上改善梯度消失問題,但是在某些情況下容易出現(xiàn)死亡ReLU問題,使得網(wǎng)絡(luò)難以訓(xùn)練。
這是由于當(dāng)x<0x<0時,ReLU函數(shù)的輸出恒為0。在訓(xùn)練過程中,如果參數(shù)在一次不恰當(dāng)?shù)母潞?#xff0c;某個ReLU神經(jīng)元在所有訓(xùn)練數(shù)據(jù)上都不能被激活(即輸出為0),那么這個神經(jīng)元自身參數(shù)的梯度永遠(yuǎn)都會是0,在以后的訓(xùn)練過程中永遠(yuǎn)都不能被激活。
一種簡單有效的優(yōu)化方式就是將激活函數(shù)更換為Leaky ReLU、ELU等ReLU的變種。
4.4.3.1 使用ReLU進(jìn)行模型訓(xùn)練 ?
使用第4.4.2節(jié)中定義的多層全連接前饋網(wǎng)絡(luò)進(jìn)行實(shí)驗(yàn),使用ReLU作為激活函數(shù),觀察死亡ReLU現(xiàn)象和優(yōu)化方法。當(dāng)神經(jīng)層的偏置被初始化為一個相對于權(quán)重較大的負(fù)值時,可以想像,輸入經(jīng)過神經(jīng)層的處理,最終的輸出會為負(fù)值,從而導(dǎo)致死亡ReLU現(xiàn)象。
?
?實(shí)例化RunnerV2類,啟動模型訓(xùn)練,打印網(wǎng)絡(luò)每層梯度值的?2?2范數(shù)。代碼實(shí)現(xiàn)如下:
# 實(shí)例化Runner類 runner = RunnerV2_2(model, optimizer, metric, loss_fn) # 啟動訓(xùn)練 runner.train([X_train, y_train], [X_dev, y_dev], num_epochs=1, log_epochs=0, save_path="best_model.pdparams", custom_print_log=custom_print_log)?
從輸出結(jié)果可以發(fā)現(xiàn),使用 ReLU 作為激活函數(shù),當(dāng)滿足條件時,會發(fā)生死亡ReLU問題,網(wǎng)絡(luò)訓(xùn)練過程中 ReLU 神經(jīng)元的梯度始終為0,參數(shù)無法更新。
針對死亡ReLU問題,一種簡單有效的優(yōu)化方式就是將激活函數(shù)更換為Leaky ReLU、ELU等ReLU 的變種。接下來,觀察將激活函數(shù)更換為 Leaky ReLU時的梯度情況。
4.4.3.2 使用Leaky ReLU進(jìn)行模型訓(xùn)練
將激活函數(shù)更換為Leaky ReLU進(jìn)行模型訓(xùn)練,觀察梯度情況。代碼實(shí)現(xiàn)如下:
?
?從輸出結(jié)果可以看到,將激活函數(shù)更換為Leaky ReLU后,死亡ReLU問題得到了改善,梯度恢復(fù)正常,參數(shù)也可以正常更新。但是由于 Leaky ReLU 中,x<0x<0 時的斜率默認(rèn)只有0.01,所以反向傳播時,隨著網(wǎng)絡(luò)層數(shù)的加深,梯度值越來越小。如果想要改善這一現(xiàn)象,將 Leaky ReLU 中,x<0x<0 時的斜率調(diào)大即可。
參考
NNDL 實(shí)驗(yàn)4(上) - HBU_DAVID - 博客園
五元錢的博客_CSDN博客-深度學(xué)習(xí),深度學(xué)習(xí)作業(yè)領(lǐng)域博主
pytorch教程之nn.Module類詳解——使用Module類來自定義模型_LoveMIss-Y的博客-CSDN博客_nn.moudle
機(jī)器學(xué)習(xí)中的數(shù)學(xué)——激活函數(shù)(四):Leaky ReLU函數(shù)_von Neumann的博客-CSDN博客_leaky relu函數(shù)
體會
paddlepaddle和pytorch之間一些函數(shù)的轉(zhuǎn)換,以及自定義梯度計算和自動梯度計算之間的區(qū)別。學(xué)習(xí)了神經(jīng)網(wǎng)絡(luò)模型的優(yōu)化問題以及死亡regu問題。更加深入了解了自定義梯度計算和自動梯度計算之間的區(qū)別。有所收獲。
總結(jié)
以上是生活随笔為你收集整理的NNDL实验五 前馈神经网络(2)自动梯度计算 优化问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深度学习炼丹-超参数调整和模型训练技巧
- 下一篇: VBS基础教程(第二版)