pytorch 正向與反向傳播的過程 獲取模型的梯度(gradient),并繪制梯度的直方圖

記錄一下怎樣pytorch框架下怎樣獲得模型的梯度

文章目錄

    • 引入所需要的庫
    • 一個簡單的函數
    • 模型梯度獲取
      • 先定義一個model
      • 如下定義兩個獲取梯度的函數
      • 定義一些過程與調用上述函數的方法
      • 可視化一下梯度的histogram

引入所需要的庫

import os
import torch
import torch.nn as nn
import torch.nn.functional as F
from collections import OrderedDict

一個簡單的函數

z=3y2=3(x+2)2z = 3y^2 = 3(x+2)^2z=3y2=3(x+2)2

out=mean(z)\text{out} = \text{mean}(z)out=mean(z)

?z?x=6(x+2)2\frac{\partial z}{\partial x} = \frac{6(x+2)}{2}?x?z?=26(x+2)?
大家想想,這里的公式為什么要除2?

代碼如下:

x = torch.tensor([[1., 2.]], requires_grad=True)
y = x + 2
z = 3 * y.pow(2)
out = z.mean()  # you can try sum() to see what is the result.
out.backward()print(f"x: {x}")
print(f"y->x: {y}")
print(f"z->y->x: {z}")
print(f"out: {out}")
print(f"out->z->y->x: {x.grad}")

輸出如下

x: tensor([[1., 2.]], requires_grad=True)
y->x: tensor([[3., 4.]], grad_fn=<AddBackward0>)
z->y->x: tensor([[27., 48.]], grad_fn=<MulBackward0>)
out: 37.5
out->z->y->x: tensor([[ 9., 12.]])

這里解釋一下,x 是定義一個tensor,并設置requires_grad=True,這個意思就是x需要計算梯度。其它的注釋已經標注挺清楚的了

模型梯度獲取

先定義一個model

class ToyModel(nn.Module):def __init__(self, in_channels, out_channels, num_classes=2):super().__init__()# tmp only for testing, not validself.tmp = nn.Conv2d(in_channels, in_channels * 2, (3, 3))self.dim = out_channelsself.conv1 = nn.Conv2d(in_channels=in_channels,out_channels=in_channels * 2,kernel_size=(3, 3),stride=(1, 1),padding=0)self.conv2 = nn.Conv2d(in_channels=in_channels * 2,out_channels=out_channels,kernel_size=(3, 3),stride=(1, 1),padding=0)self.pool = nn.AdaptiveAvgPool2d(output_size=(1))self.fc = nn.Linear(out_channels, num_classes, bias=False)def forward(self, x):x = F.relu(self.conv1(x))x = F.relu(self.conv2(x))x = self.pool(x)x = self.fc(x.view(-1, self.dim))return x

如下定義兩個獲取梯度的函數

def get_model_histogram(model):"""Description:- get norm gradients from model, and store in a OrderDictArgs:- model: (torch.nn.Module), torch modelReturns:- grads in OrderDict"""grads = OrderedDict()for name, params in model.named_parameters():grad = params.gradif grad is not None:tmp = {}params_np = grad.numpy()histogram, bins = np.histogram(params_np.flatten())tmp['histogram'] = list(histogram)tmp['bins'] = list(bins)grads[name] = tmpreturn grads
def get_model_norm_gradient(model):"""Description:- get norm gradients from model, and store in a OrderDictArgs:- model: (torch.nn.Module), torch modelReturns:- grads in OrderDict"""grads = OrderedDict()for name, params in model.named_parameters():grad = params.gradif grad is not None:grads[name] = grad.norm().item()return grads

定義一些過程與調用上述函數的方法

torch.manual_seed(0)
num_data = 40
toy_model = ToyModel(3, 64, 2)
data = torch.randn(num_data, 3, 224, 224)
label = torch.randint(0, 2, (num_data,))
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(toy_model.parameters(), lr=1e-3)
toy_model.train()
for i, data in enumerate(data):data = data.unsqueeze(0)out = toy_model(data)target = label[i].unsqueeze(0)loss = criterion(out, target)loss.backward()if (i + 1) % 10 == 0:print('=' * 80)# fix 2022-04-27 histo not defined# print(get_model_norm_gradient(toy_model))histo = (get_model_histogram(toy_model))print(histo)optimizer.step()optimizer.zero_grad()

get model norm gradient的輸出如下

================================================================================
OrderedDict([('conv1.weight', 0.1473149210214615), ('conv1.bias', 0.16713829338550568), ('conv2.weight', 0.9203198552131653), ('conv2.bias', 0.5442095994949341), ('fc.weight', 1.7258217334747314)])
================================================================================
OrderedDict([('conv1.weight', 0.0349930003285408), ('conv1.bias', 0.03801438584923744), ('conv2.weight', 0.20729205012321472), ('conv2.bias', 0.12616902589797974), ('fc.weight', 0.39913201332092285)])
================================================================================
OrderedDict([('conv1.weight', 0.07812522351741791), ('conv1.bias', 0.08833323419094086), ('conv2.weight', 0.49012720584869385), ('conv2.bias', 0.2875416576862335), ('fc.weight', 0.9168939590454102)])
================================================================================
OrderedDict([('conv1.weight', 0.14530049264431), ('conv1.bias', 0.16511967778205872), ('conv2.weight', 0.9190732836723328), ('conv2.bias', 0.5398930907249451), ('fc.weight', 1.7265493869781494)])
torch.manual_seed(0)
num_data = 40
toy_model = ToyModel(3, 64, 2)
data = torch.randn(num_data, 3, 224, 224)
label = torch.randint(0, 2, (num_data,))
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(toy_model.parameters(), lr=1e-3)
toy_model.train()
for i, data in enumerate(data):data = data.unsqueeze(0)out = toy_model(data)target = label[i].unsqueeze(0)loss = criterion(out, target)loss.backward()if (i + 1) % 10 == 0:print('=' * 80)# fix 2022-04-27 histo not defined# print(str(get_model_histogram(toy_model)))histo = (get_model_histogram(toy_model))print(histo)optimizer.step()optimizer.zero_grad()

get model histogram 輸出如下,輸出太多,只顯示最后一條輸入了

================================================================================
OrderedDict([('conv1.weight', {'histogram': [4, 2, 13, 27, 76, 22, 11, 5, 1, 1], 'bins': [-0.036256444, -0.028072663, -0.019888882, -0.0117051015, -0.0035213209, 0.0046624597, 0.012846241, 0.021030022, 0.029213801, 0.037397582, 0.045581363]}), ('conv1.bias', {'histogram': [1, 2, 0, 0, 1, 0, 1, 0, 0, 1], 'bins': [-0.028756114, -0.012518765, 0.0037185834, 0.019955931, 0.03619328, 0.05243063, 0.06866798, 0.08490533, 0.101142675, 0.11738002, 0.13361737]}), ('conv2.weight', {'histogram': [15, 10, 35, 245, 1828, 970, 230, 68, 40, 15], 'bins': [-0.07653718, -0.060686104, -0.044835035, -0.028983962, -0.013132891, 0.0027181804, 0.018569252, 0.034420323, 0.050271396, 0.066122465, 0.08197354]}), ('conv2.bias', {'histogram': [1, 0, 1, 8, 12, 28, 5, 6, 0, 3], 'bins': [-0.21087514, -0.16971013, -0.1285451, -0.0873801, -0.04621508, -0.005050063, 0.036114953, 0.07727997, 0.11844498, 0.15961, 0.20077501]}), ('fc.weight', {'histogram': [1, 7, 11, 12, 33, 33, 12, 11, 7, 1], 'bins': [-0.41966814, -0.33573452, -0.2518009, -0.16786726, -0.08393363, 0.0, 0.08393363, 0.16786726, 0.2518009, 0.33573452, 0.41966814]})])

可視化一下梯度的histogram

import matplotlib.pyplot as plt
import matplotlib%matplotlib inline
  • 可視化conv2.weight
data = histo['conv2.weight']
bins = data['bins']
histogram = data['histogram']
max_idx = np.argmax(histogram)
min_idx = np.argmin(histogram)
width = abs(bins[max_idx] - bins[min_idx])plt.figure(figsize=(9, 6))
plt.bar(bins[:-1], histogram, width=width)
plt.show()

在這里插入圖片描述

  • 可視化conv2.bias
data = histo['conv2.bias']
bins = data['bins']
histogram = data['histogram']
max_idx = np.argmax(histogram)
min_idx = np.argmin(histogram)
width = abs(bins[max_idx] - bins[min_idx])plt.figure(figsize=(9, 6))
plt.bar(bins[:-1], histogram, width=width)
plt.show()

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/260453.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/260453.shtml
英文地址,請注明出處:http://en.pswp.cn/news/260453.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2012-9

響應式設計的典范 http://www.bostonglobe.com/ 網站測試頁面 http://www.webpagetest.org/ 編程算法 http://blog.sina.com.cn/s/articlelist_1647038822_1_1.html C Programmers Cookbook http://www.cppblog.com/mzty/category/7609.html Blade 是一個現代構建系統&#xff…

PV操作 (轉載)

PV操作與信號量的處理相關&#xff0c;P表示通過的意思&#xff0c;V表示釋放的意思。信號量是最早出現的用來解決進程同步與互斥問題的機制&#xff0c;包括一個稱為信號量的變量及對它進行的兩個原語操作。 信號量&#xff08;semaphore&#xff09;的數據結構為一個值和一個…

ubuntu升級python_Ubuntu 升級python3為更高版本【已實測】

2020-04-13 更新安裝步驟&#xff1a; 1. 先update一下 sudo apt update 2. 安裝依賴庫 sudo apt-get install zlib1g-dev libbz2-dev libssl-dev libncurses5-dev libsqlite3-dev libreadline-dev tk-dev libgdbm-dev libdb-dev libpcap-dev xz-utils libexpat1-dev liblzma-d…

mysql5.0 java連接_Java連接mysql5.0

網上的資料真爛&#xff0c;千篇一律的拷貝的&#xff0c;根本不能用&#xff0c;鄙視&#xff01; 正題&#xff1a; 到MYSQL網站下載mysql-connector-java-5.0.4.zip文件&#xff0c;解壓&#xff1b; 解壓后有一個文件&#xff1a;mysql-connector-java-5.0.4-bin.jar 把這個…

Framework打包

2019獨角獸企業重金招聘Python工程師標準>>> iOS app需要在許多不同的CPU架構下運行&#xff1a; arm7: 在最老的支持iOS7的設備上使用 arm7s: 在iPhone5和5C上使用 arm64: 運行于iPhone5S的64位 ARM 處理器 上 i386: 32位模擬器上使用 x86_64: 64為模擬器上使用…

windows 10 下利用WSL的Linux環境實現vscode C/C++環境的配置

本文主要結合二個工具&#xff0c;介紹如何在windows搭建Linux開發環境&#xff1a; WSL(Windows Subsystem for Linux)VSCode(Visual Studio Code) 文章目錄WSL安裝VSCode安裝配置Linux下的C/C環境1. 打開WSL的控制臺2. 更新ubuntu軟件3. 安裝GCC和GDB4. 配置VSCode(1). 打開…

java類初始化順序

轉自&#xff1a;http://zangweiren.iteye.com/blog/208122 對于靜態變量、靜態初始化塊、變量、初始化塊、構造器&#xff0c;它們的初始化順序以此是&#xff08;靜態變量、靜態初始化塊&#xff09;>&#xff08;變量、初始化塊&#xff09;>構造器。我們也可以通過下…

Java 8 - Interface Default Method接口默認方法

Java 8 相比于Java 7 推出了幾大特色&#xff08;features&#xff09;(接口默認方法)default methods in interface, &#xff08;接口靜態方法&#xff09;static method in interface, 函數編程(functional programming)&#xff0c; lamda expression, stream API.這里首先…

Windows 11下 WSL使用 jupyter notebook

這里寫目錄標題前言在WSL下的配置測試運行更優雅的啟動方法配置jupyter生成默認配置文件生成秘鑰修改配置文件nohup啟動前言 一直都使用jupyter notebook&#xff0c;不管做數據分析&#xff0c;還是調試代碼&#xff0c;還有寫文章都是。但是好像在WSL下又不好使。看了網上有…

sql2000導出mysql_如何將sql2000的數據庫導入到mysql中?

展開全部先用SQl2000導出e68a843231313335323631343130323136353331333262373366文本文件&#xff0c;把后綴名改為CSv&#xff0c;再從Mysql中一導入OK參考&#xff1a;第一種是安裝mysql ODBC&#xff0c;利用sql server的導出功能&#xff0c;選擇mysql數據源&#xff0c;進…

實現日、周、月排行統計 sql

在如今很多系統中&#xff0c;都需要進行日、周、月排行統計&#xff0c;但是在網上尋找 了一番&#xff0c;發現很多都是相對的周、月排行&#xff0c;即周排行則用當前時間減去7天。這樣我個人認為并不恰當。如月排行中&#xff0c;假設今天是4月22日,則從3月22日至4月22日之…

產品運行所需的信息檢索失敗_為服務業注入新活力,華北工控推出服務機器人專用計算機產品方案...

近年來&#xff0c;隨著人口老齡化趨勢加快和信息科技革命的持續推進&#xff0c;服務機器人已經被當作社會勞動力的一部分在醫療、教育、餐飲等行業廣泛應用&#xff0c;市場潛力巨大。01、需求帶動消費&#xff0c;科技改變服務服務機器人是國內智能機器人產業發展最快的分支…

Windows更新沒有更新提示:從windows 10升級到Windows 11,并WSL下配置cuda

文章目錄從windows 10 升級到Windows 11安裝WSL的安裝配置cuda從windows 10 升級到Windows 11 升級的方法有很多種&#xff0c;各大網站都有。有更新提示的按更新提示操作即可。我的是一直都沒有更新提示&#xff0c;也搜索過網上的一些方法&#xff0c;但都不行。還是沒法更新…

js修改css樣式屬性_這個筆記《CSS樣式的常見屬性及值》,讓菜鳥輕松學會包粽子...

常見樣式屬性及值字體:font-family-size-style: normal(正常)|italic(傾斜)|oblique-weight: normal|bold(粗體)如果組合起來編寫: font: style weight size family字體大小的單位可以是 px, em, rem, pt, cm, mm, in, pc文本:colortext-align(水平對齊方式): left|center|righ…

7.java.lang.IllegalAccessException

java.lang.IllegalAccessException 沒有訪問權限 當應用程序要調用一個類&#xff0c;但當前的方法即沒有對該類的訪問權限便會出現這個異常。對程序中用了Package的情況下要注意這個異常

在 VirtualBox 中 CentOS 網絡設置

轉自&#xff1a;本文發表于水景一頁。永久鏈接&#xff1a;<http://cnzhx.net/blog/minimal-centos-in-virtualbox/>。轉載請保留此信息及相應鏈接。 4. 設置 按照上面的方法安裝之后&#xff0c;還需要一些簡單的設置&#xff0c;比如網絡訪問。然后既然是做網頁服務器…

mysql 熱塊_mysql 優化

數據庫層面&#xff1a;應用系統層面優化SQL優化SQL優化一般通過分析慢查詢日志來抓取長事務高消耗的sql&#xff0c;通過結合具體業務&#xff0c;對sql邏輯進行分析and精簡&#xff0c;or重寫sql。通過配置slow_query_log1和log_queries_not_using_indexes1啟動慢查詢日志記錄…

vscode C++ 分文件、文件夾編譯配置與錯誤解決

文章目錄問題includesourceout配置過程遇到的問題與解決遇到的問題1解決步驟1. ctrl shift p2. 配置json文件修改task.json文件修改launch.json可能遇到的錯誤1. collect2: error: ld returned 1 exit status2. /mnt/d/tmp/c/source/add.cpp:3:10: fatal error: add.h: No su…

gc就是fullgc嗎 major_線上出現fullgc問題如何排查?

1.問題描述線上出現fullgc報警&#xff0c;每5分鐘一次2.背景知識1. 程序執行了System.gc()執行了jmap -histo:live pid命令 在執行minor gc的時候進行的一系列檢查 執行Minor GC的時候&#xff0c;JVM會檢查老年代中最大連續可用空間是否大于了當前新生代所有對象的總大小。 …

修改 jquery.validate.js 支持非form標簽

嘗試使用markdown來寫一篇blog&#xff0c;啦啦啦 源代碼傳送門&#xff1a;github 在特殊情況下我們使用jquery.validate.js對用戶輸入的內容做驗證的時候&#xff0c;表單并不是一定包含在form之中&#xff0c;有可能是一個div彈層&#xff0c;有可能是嵌套在form里面的一個d…