pytorch面試總結

一. pytorch多卡訓練的原理

原理:
(1)將模型加載到一個指定的主GPU上,然后將模型淺拷貝到其它的從GPU上;
(2)將總的batch數(shù)據等分到不同的GPU上(坑:需要先將數(shù)據加載到主GPU上);
(3)每個GPU根據自己分配到的數(shù)據進行forward計算得到loss,并通過backward得到權重梯度;
(4)主GPU將所有從GPU得到的梯度進行合并并用于更新模型的參數(shù)。
實現(xiàn):
(1)模型方面

device_ids = [0, 1, 2, 3]
model = Model(input_size, output_size)
model = nn.DataParallel(model, device_ids=device_ids) #單卡沒有這行代碼
model = model.cuda(device_ids[1]) #指定哪塊卡為主GPU,默認是0卡

(2)數(shù)據方面

for data in data_loader:
    input_var = Variable(data.cuda(device_ids[1])) #默認指定用0卡先加載數(shù)據就會報錯
    output = model(input_var)

二. pytorch中gather和scatter_

  1. gather(聚合操作)
    (1)函數(shù)原型:torch.gather(input, dim, index, out=None);
    (2)函數(shù)功能:對于out指定位置上的值,去尋找input里面對應的索引位置,根據是index;
    (3)三維數(shù)組的通項公式
out[i][j][k] = input[index[i][j][k]][j][k]  # if dim = 0
out[i][j][k] = input[i][index[i][j][k]][k]  # if dim = 1
out[i][j][k] = input[i][j][index[i][j][k]]  # if dim = 2
  1. scatter_(分散操作)
    (1)函數(shù)原型:Tensor.scatter_(dim, index, src)
    (2)函數(shù)功能:src(或者說input)指定位置上的值,去分配給output對應索引位置,根據是index;
    (3)三維數(shù)組的通項公式:
self[index[i][j][k]][j][k] = src[i][j][k]  # if dim == 0
self[i][index[i][j][k]][k] = src[i][j][k]  # if dim == 1
self[i][j][index[i][j][k]] = src[i][j][k]  # if dim == 2

三. pytorch中torch.Tensor()和torch.tensor()的相同點和區(qū)別

  1. 相同點
    Tensor和tensor都能用于生成新的張量
>>> a=torch.Tensor([1,2])
>>> a
tensor([1., 2.])
>>> a=torch.tensor([1,2])
>>> a
tensor([1, 2])
  1. 不同點
    torch.Tensor()是python類,是torch.FloatTensor()的別名,使用torch.Tensor()會調用Tensor類的構造函數(shù),生成float類型的張量;
    而torch.tensor()僅僅是python的函數(shù),函數(shù)原型是torch.tensor(data, dtype=None, device=None, requires_grad=False),其中data可以是scalar,list,tuple,numpy array等等。
    然后torch.tensor會從data中的數(shù)據部分進行拷貝(而不是引用),根據原始數(shù)據類型生成相應的 torch.LongTensor、torch.FloatTensor和torch.DoubleTensor。比如:
>>> a=torch.tensor([1,2])
>>> a.type()
'torch.LongTensor'

>>> a=torch.tensor([1.,2.])
>>> a.type()
'torch.FloatTensor'

>>> a=np.zeros(2,dtype=np.float64)
>>> a=torch.tensor(a)
>>> a.type()
'torch.DoubleTensor'

四. pytorch中Variable的理解

torch.autograd.Variable是Autograd的核心類,它封裝了Tensor,并整合了反向傳播的相關實現(xiàn)。Variable包含了三個屬性:
(1)data:存儲了Tensor本體的數(shù)據;
(2)grad:保存了data的梯度,其本身也是個Variable,shape與data相同;
(3)grad_fn:指向Function對象,用于反向傳播的梯度計算。但是在pytorch0.4之后,將Variable與Tensor整合到了一起,聲明torch.tensor也包含這三個屬性。

五. pytorch中backward()的理解

https://blog.csdn.net/sinat_28731575/article/details/90342082

六. tensorflow中variable和get_variable的區(qū)別

(1)variable是用來創(chuàng)建變量的,當兩個變量的名字在同一作用域內相同時,tensorflow會自動將第二個定義的variable的名字加上"_1",則會生成新的name,如果使用在name_scope內,則會在name的前面加上name_scope名字的前綴;
(2)get_variable的功能是用來進行變量共享的,當變量不存在時,則會自動創(chuàng)建該變量。如果存在時,需要設置reuse=True來獲取該變量,實現(xiàn)變量共享。需要注意的是,get_variable在variable_scope內使用才會給name加上前綴,在name_scope中使用并不會。

七. tensorflow中節(jié)點和邊代表的什么

(1)節(jié)點代表著多種功能,比如說輸入,變量初始化,運算,控制,輸出等;
(2)邊代表輸入與輸出之間的關系,即數(shù)據流動的方向。

八. pytorch中train和eval有什么不同

(1). model.train()——訓練時候啟用
啟用 BatchNormalization 和 Dropout,將BatchNormalization和Dropout置為True
(2). model.eval()——驗證和測試時候啟用
不啟用 BatchNormalization 和 Dropout,將BatchNormalization和Dropout置為False

train模式會計算梯度,eval模式不會計算梯度。

九、caffe的im2col

參考 caffe在實現(xiàn)卷積的時候,將kernel展開成行向量(每一行表示一個輸出channel,output channel為幾,就有幾個行向量),將input tensor展開成列向量(im2col操作),但是是根據kernel的shape展開,(kernel能滑動多少次,就有多少列),不同的input channel被分成了很多矩陣塊,但是都是“縱向放置”,然后將kernel和input tensor做矩陣乘法,得到output_channels行,output_h * output_w列的矩陣,每一行都可以展開成一張輸出特征圖(由于圖像數(shù)據是連續(xù)存儲的,只需要按行按列排滿即可)。

PS:不同框架的訪存機制不一樣,所以會有行列相反這樣的區(qū)別。python和c++的數(shù)據存儲是行優(yōu)先,matlab是列優(yōu)先。所以,在caffe框架下,im2col是將一個小窗的值展開為一行,而在matlab中則展開為列。所以說,行列的問題沒有本質區(qū)別,目的都是為了在計算時讀取連續(xù)的內存。

十. tensorflow底層實現(xiàn)卷積的方式

參考 pytorch,tensorflow,caffe底層實現(xiàn)卷積的核心都是im2col, 這里以tensorflow為例。

tf.nn.conv2d()函數(shù)的定義為:
conv2d(input,filter,strides,padding,use_cudnn_on_gpu=True,data_format="NHWC",dilations=[1,1,1,1],name=None)

給定 4-D input 和 filter tensors計算2-D卷積,其中input tensor 的 shape是: [B, H, W, C],filter / kernel tensor 的 shape是: [filter_height, filter_width, in_channels, out_channels]

卷積op執(zhí)行方式:

  1. 將filter展開為一個 shape 為[filter_height * filter_width * in_channels, out_channels] 大小的2-D 矩陣。
  2. 從 input tensor按照每個filter位置上提取圖像patches來構成一個虛擬的shape大小為[batch, out_height, out_width,filter_height * filter_width * in_channels]的tensor 。(相當于在input每個卷積核的位置上(包含了同一位值對應的不同channel)提取patches)
    ps:把輸入圖像要經行卷積操作的這一區(qū)域展成列向量的操作通常稱為im2col
  3. 對每個patch, 右乘以 filter matrix.得到[batch, out_height, out_width,out_channels]大小的輸出。(Input maps的第一列×kernels的第一行,得到輸出的第一個值,Input maps的第i列×kernels的第j行,得到輸出特征圖第i列第 j行的值)

十一. Pytorch和tensorflow區(qū)別,底層分別是怎么實現(xiàn)動態(tài)圖和靜態(tài)圖的?

【參考】

tensorflow實現(xiàn)反向傳播:

import tensorflow as tf
weight = tf.Variable(tf.random_uniform([1], -1.0, 1.0))
biases = tf.Variable(tf.zeros([1]))
y = weight * x_data + biases

loss = tf.reduce_mean(tf.square(y - y_data)) # 計算loss
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.05)

train_step = optimizer.minimize(loss)

init = tf.initialize_all_variables()
sess.run(init)

sess.run(train_step, feed_dict={x_data:x, y_data:y})

pytorch實現(xiàn)反向傳播:loss.backward()

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容