溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

pytorch怎么定義新的自動(dòng)求導(dǎo)函數(shù)

發(fā)布時(shí)間:2022-12-15 10:00:39 來(lái)源:億速云 閱讀:101 作者:iii 欄目:開發(fā)技術(shù)

今天小編給大家分享一下pytorch怎么定義新的自動(dòng)求導(dǎo)函數(shù)的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來(lái)了解一下吧。

    pytorch定義新的自動(dòng)求導(dǎo)函數(shù)

    在pytorch中想自定義求導(dǎo)函數(shù),通過實(shí)現(xiàn)torch.autograd.Function并重寫forward和backward函數(shù),來(lái)定義自己的自動(dòng)求導(dǎo)運(yùn)算。

    直接上代碼,定義一個(gè)ReLu來(lái)實(shí)現(xiàn)自動(dòng)求導(dǎo)

    import torch
    
    class MyRelu(torch.autograd.Function):
        @staticmethod
        def forward(ctx, input):
            # 我們使用ctx上下文對(duì)象來(lái)緩存,以便在反向傳播中使用,ctx存儲(chǔ)時(shí)候只能存tensor
            # 在正向傳播中,我們接收一個(gè)上下文對(duì)象ctx和一個(gè)包含輸入的張量input;
            # 我們必須返回一個(gè)包含輸出的張量,
            # input.clamp(min = 0)表示講輸入中所有值范圍規(guī)定到0到正無(wú)窮,如input=[-1,-2,3]則被轉(zhuǎn)換成input=[0,0,3]
            ctx.save_for_backward(input)
            
            # 返回幾個(gè)值,backward接受參數(shù)則包含ctx和這幾個(gè)值
            return input.clamp(min = 0)
    
        @staticmethod
        def backward(ctx, grad_output):
            # 把ctx中存儲(chǔ)的input張量讀取出來(lái)
            input, = ctx.saved_tensors
            
            # grad_output存放反向傳播過程中的梯度
            grad_input = grad_output.clone()
            
            # 這兒就是ReLu的規(guī)則,表示原始數(shù)據(jù)小于0,則relu為0,因此對(duì)應(yīng)索引的梯度都置為0
            grad_input[input < 0] = 0
            return grad_input

    進(jìn)行輸入數(shù)據(jù)并測(cè)試

    dtype = torch.float
    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    # 使用torch的generator定義隨機(jī)數(shù),注意產(chǎn)生的是cpu隨機(jī)數(shù)還是gpu隨機(jī)數(shù)
    generator=torch.Generator(device).manual_seed(42)
    
    # N是Batch, H is hidden dimension,
    # D_in is input dimension;D_out is output dimension.
    N, D_in, H, D_out = 64, 1000, 100, 10
    
    x = torch.randn(N, D_in, device=device, dtype=dtype,generator=generator)
    y = torch.randn(N, D_out, device=device, dtype=dtype, generator=generator)
    
    w1 = torch.randn(D_in, H, device=device, dtype=dtype, requires_grad=True, generator=generator)
    w2 = torch.randn(H, D_out, device=device, dtype=dtype, requires_grad=True, generator=generator)
    
    learning_rate = 1e-6
    for t in range(500):
        relu = MyRelu.apply
        # 使用函數(shù)傳入?yún)?shù)運(yùn)算 
        y_pred = relu(x.mm(w1)).mm(w2)
    	# 計(jì)算損失
        loss = (y_pred - y).pow(2).sum()
        if t % 100 == 99:
            print(t, loss.item())
        # 傳播
        loss.backward()
        with torch.no_grad():
            w1 -= learning_rate * w1.grad
            w2 -= learning_rate * w2.grad
           	
            w1.grad.zero_()
            w2.grad.zero_()

    pytorch自動(dòng)求導(dǎo)與邏輯回歸

    自動(dòng)求導(dǎo)

    pytorch怎么定義新的自動(dòng)求導(dǎo)函數(shù)

    retain_graph設(shè)為True,可以進(jìn)行兩次反向傳播

    pytorch怎么定義新的自動(dòng)求導(dǎo)函數(shù)

    pytorch怎么定義新的自動(dòng)求導(dǎo)函數(shù)

    邏輯回歸

    pytorch怎么定義新的自動(dòng)求導(dǎo)函數(shù)

    pytorch怎么定義新的自動(dòng)求導(dǎo)函數(shù)

    import torch
    import torch.nn as nn
    import matplotlib.pyplot as plt
    import numpy as np
    torch.manual_seed(10)
    #========生成數(shù)據(jù)=============
    sample_nums = 100
    mean_value = 1.7
    bias = 1
    n_data = torch.ones(sample_nums,2)
    x0 = torch.normal(mean_value*n_data,1)+bias#類別0數(shù)據(jù)
    y0 = torch.zeros(sample_nums)#類別0標(biāo)簽
    x1 = torch.normal(-mean_value*n_data,1)+bias#類別1數(shù)據(jù)
    y1 = torch.ones(sample_nums)#類別1標(biāo)簽
    train_x = torch.cat((x0,x1),0)
    train_y = torch.cat((y0,y1),0)
    #==========選擇模型===========
    class LR(nn.Module):
        def __init__(self):
            super(LR,self).__init__()
            self.features = nn.Linear(2,1)
            self.sigmoid = nn.Sigmoid()
    
        def forward(self,x):
            x = self.features(x)
            x = self.sigmoid(x)
            return x
    
    lr_net = LR()#實(shí)例化邏輯回歸模型
    
    #==============選擇損失函數(shù)===============
    loss_fn = nn.BCELoss()
    #==============選擇優(yōu)化器=================
    lr = 0.01
    optimizer = torch.optim.SGD(lr_net.parameters(),lr = lr,momentum=0.9)
    
    #===============模型訓(xùn)練==================
    for iteration in range(1000):
        #前向傳播
        y_pred = lr_net(train_x)#模型的輸出
        #計(jì)算loss
        loss = loss_fn(y_pred.squeeze(),train_y)
        #反向傳播
        loss.backward()
        #更新參數(shù)
        optimizer.step()
    
        #繪圖
        if iteration % 20 == 0:
            mask = y_pred.ge(0.5).float().squeeze() #以0.5分類
            correct = (mask==train_y).sum()#正確預(yù)測(cè)樣本數(shù)
            acc = correct.item()/train_y.size(0)#分類準(zhǔn)確率
    
            plt.scatter(x0.data.numpy()[:,0],x0.data.numpy()[:,1],c='r',label='class0')
            plt.scatter(x1.data.numpy()[:,0],x1.data.numpy()[:,1],c='b',label='class1')
    
            w0,w1 = lr_net.features.weight[0]
            w0,w1 = float(w0.item()),float(w1.item())
            plot_b = float(lr_net.features.bias[0].item())
            plot_x = np.arange(-6,6,0.1)
            plot_y = (-w0*plot_x-plot_b)/w1
    
            plt.xlim(-5,7)
            plt.ylim(-7,7)
            plt.plot(plot_x,plot_y)
    
            plt.text(-5,5,'Loss=%.4f'%loss.data.numpy(),fontdict={'size':20,'color':'red'})
            plt.title('Iteration:{}\nw0:{:.2f} w1:{:.2f} b{:.2f} accuracy:{:2%}'.format(iteration,w0,w1,plot_b,acc))
            plt.legend()
            plt.show()
            plt.pause(0.5)
            if acc > 0.99:
                break

    以上就是“pytorch怎么定義新的自動(dòng)求導(dǎo)函數(shù)”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI