零基礎學習人工智慧—Python—Pytorch學習(一)

kiba518發表於2024-08-07

前言

其實學習人工智慧不難,就跟學習軟體開發一樣,只是會的人相對少,而一些會的人寫文章,做影片又不好好講。
比如,上來就跟你說要學習張量,或者告訴你張量是向量的多維度等等模式的講解;目的都是讓別人知道他會這個技術,但又不想讓你學。
對於學習,多年的學習經驗,和無數次的回顧學習過程,都證明了一件事,如果一篇文章,一個影片,一個課程,我沒學明白,那問題一定不在我,而是上課的主動或被動的不想讓我學會,所以,出問題的一定是學習資料。
比如英語,當真會了以後,再回去看自己之前學過的課,就知道了,那是英語老師沒好好教,哪有真正想讓你學會英語的人,會告訴你【come=來,out=出去】呀,認認真真按高中大學老師教的方法學習英語。記單詞背片語,一百年學不會英語。
比如線性代數,等會了以後,再回去看之前看不懂的課程影片,就知道了,是上課老師估計模糊的關鍵資訊。
學習軟體開發,相信大家也都有類似的經驗,當你想學一個知識點時,各種搜尋,就是看不懂,最後學會的原因只有兩種,1,你找到了真正的教你知識的文章,2,你透過搜尋的資訊,自己悟了出來。這其實就是在證明,絕大多數的文章和影片都不想真正教你,包括正規學校的老師和教材。

入門學習

首先,介紹一下我學習的資料,我透過一通搜尋,終於找到了最好的學習資料,該影片是認真教你學習的,唯一的缺點可能就是,上課的人說的是英語,有點印度口音。不過,個人感覺他帶點口語,反而更好聽懂。
重點關注一下下面單詞影片裡會多次提到,注意了後就不會被英語卡住了。
numpy:這個單詞,這不是個單詞,但是是python的庫。
vector:向量,下面有解釋。
tensor:張量,下面有解釋。
gradient:梯度,指的就是我下面的提到的求偏導數。
地址是:https://www.youtube.com/watch?v=exaWOE8jvy8&list=PLqnslRFeH2UrcDBWF5mfPGpqQDSta6VK4&index=1

安裝

pytorch和tensorflow都是做人工智慧的,prtorch的函式相對更友好,所以入門更高效。
pytorch官網地址:https://pytorch.org/get-started/locally/
使用pytorch前,先安裝環境,我這裡使用了vscode,安裝完vscode後,在擴充套件裡把python的包瞎按一些就行。
一般來講學習都使用cpu版本。安裝命令如下:

pip3 install torch torchvision torchaudio

如果使用gpu,安裝命令如下:

pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124

安裝完成後,執行程式碼,如果執行成功,則安裝成功。

import torch
x =torch.ones(1)
print(x)

名詞介紹

矩陣:就是我們的表。
向量(vector):這種只有一行/一列的矩陣,叫向量。

1,1,0

二維張量(tensor2D):這有多行多列的矩陣叫二維張量。

1,1,0
1,0,1

三維張量(tensor3D),就是三維陣列。
多維張量同多維陣列。
為什麼叫向量或者張量?我們把[1,1,0]換個想象就行,[1,1,0]是自原點向x=1,y=1,z=0發射出去的線,那[1,1,0]就不在是個資料了,就變成張量了。但本質還是資料。這地方不要細究,理解就可以了,畢竟我們不是研究數學的。

程式碼入門

使用pytorch進行張量的基礎。

import torch
import numpy as np
x=torch.empty(1) # 建立一個只有一個元素的向量(vector),元素值是未定義的,未定義的就是0,列印出來是【0.】,這是因為預設的元素型別是float32
print(x)
x=torch.empty(3)  # 建立一個有三個元素的向量(vector),元素值是未定義的
print(x)
x=torch.empty(3,2)  # 建立一個矩陣,,元素值是未定義的
print(x) 

x=torch.rand(3,2)  # 建立一個3*2的矩陣,並隨機賦值
print(x)
x=torch.zeros(3,2)  # 建立一個3*2的矩陣,並賦值0
print(x)

x=torch.ones(2,2)  # 建立一個2*2的矩陣,並賦值1,列印出來是【1.】
print(x)
print("列印型別")
print(x.dtype) #dtype是data type,會列印出元素的型別,列印內容是torch.float32
x=torch.ones(3,3,dtype=torch.int)  # 建立一個3*3的矩陣,並賦值1,列印出來是【1】,這會就不帶.了
print(x) 
x=torch.ones(3,3,dtype=torch.double)  # 建立一個3*3的矩陣,並賦值1,列印出來是【1.】,double型別又帶.了
print(x)
print(x.size()) #size是個函式,這樣列印會列印出toString()的感覺,值是【torch.Size([3, 3])】
print(x.size().numel()) # 元素個數,值是9
x=torch.tensor([2.2,3.1]) # 自定義張量
print(x)
print("===========加法============")
x=torch.ones(3,3,dtype=torch.int)  # 建立一個3*3的矩陣,並賦值1,列印出來是【1】,這會就不帶.了
print(x)
y =torch.ones(3,3,dtype=torch.int)   
print(y)
z=x+y #矩陣相加
print(z)
z=torch.add(x,y) #矩陣相加
print(z)
print("===========計算print(y.add_(x))============")
print(y.add_(x)) #把x加到y中去
print("===========減法============")
z=x-y #矩陣相減
print(z)
z=torch.sub(x,y) #矩陣相減
print(z)
print("===========計算print(y.sub_(x))============")
print(y.sub_(x)) #把x減去從y中
print("===========乘法============") #這個乘法是元素相對的相乘,而不是線性代數的 A23*A32
z=x*y #矩陣相乘 
print(z)
z=torch.mul(x,y)
print(z)
print(y.mul_(x))
print("===========除法============")
z=x/y #矩陣相乘除
print(z)
z=torch.div(x,y)
print(z)
print("===========列表============")
x=torch.rand(5,4)  # 建立一個3*2的矩陣,並隨機賦值
print(x[:,0]) #列印全部行,但只取第一列
print(x[0,:]) #列印全部列,但只取第一行
print(x[0,0]) #列印i=0 j=0的元素
print(x[1,1].item()) #如果只取一個元素值,則可以取他的真實值
print(x)
print("===========view可以resize tensor============")
x=torch.rand(5,4) 
y=x.view(20) #返回一個新的張量,這個是返回一個1行的20個元素的張量
print(y)
y=x.view(-1,10)
print(y) # 這個是返回2行,每行10個,他做了自動適配
print(y.size())#輸出size
#print(x.view(-1,7)) # 這個自動適配不了,因為不能被7整除
print("===========numpy numpy只能在cpu上使用,不能在gpu上使用============")
a=torch.ones(5) #行向量,值是1,元素是5
b=a.numpy() #返回 numpy.ndarray型別的numpy下的張量,相當於轉了型別,用於計算,該函式有引數 預設是false,表示使用cpu
print(b,type(b))
 #這裡雖然a轉了型別到b,但b和a是物件封裝,引用地址一樣 所以當我們給a+1時,b也會+1
a.add_(1)
print(a)
print(b)#雖然a b型別不一樣,但值都改變了
print("===========從numpy.ndarray轉成tensor張量的方式============")
a = np.ones(5) #行向量 5元素 值是1
b =torch.from_numpy(a) #numpy的ndarray轉tensor 同樣是裝箱拆箱 修改a的值 b也會變
a+=1
print(b)
print(a)
print("===========gpu============")
if(torch.cuda.is_available()):
    #CUDA 是指 NVIDIA 的平行計算平臺和程式設計模型,它利用圖形處理單元 (GPU) 的處理能力來加速計算密集型任務
    device =torch.device("cuda") #獲取cuda驅動
    x=torch.ones(5,device=device)#建立時指定了使用cpu的記憶體
    y=torch.ones(5)#建立時使用cpu的記憶體
    y=y.to(device)#將y轉到gpu
    z=x+y #這個操作是在gpu的記憶體上進行了
    #z.numpy()#這個不能執行,因為z在gpu的記憶體上
    z =z.to("cpu") #轉回到cpu
else:
    print("this is cpu")

requires_grad例子。
這裡要點高數基礎。
首先是導數,這個大家忘了的可以百度一下。
偏導數:這個就是f(x,y)=x+y這樣的函式求導,只是對x求導時,把y當常量c,反之亦然。

print("===========requires_grad 例子1============")
#使用自動微分(autograd)
x=torch.ones(5,requires_grad=True) #預設requires_grad是false  1,計算梯度:requires_grad 是一個布林引數,用於指定一個張量是否需要計算梯度 2,自動求導:使用 requires_grad=True 的張量進行的所有操作都會被記錄,以便稍後使用 backward() 方法進行自動求導。
print(x)
# 對張量進行一些操作
y = x + 2
print(y)
# 再進行一些操作
z = y * y * 3
print("======分割線1=====")
print(z)
out = z.mean() #是一個張量操作,它計算張量 z 的所有元素的平均值。 看做f(x)=(x1+x2+x3+x4)/4 然後對每個x求偏導,在把值帶回去
print("======分割線2=====")
print(out)
# 進行反向傳播,計算梯度
out.backward()
print("======分割線3=====")
print(x.grad)  # 輸出x的梯度
print("===========requires_grad 例子2============")
# 建立一個張量,並指定需要計算梯度
x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True) 
# 定義一個標量函式 平方在求和 相當於函式 f()= x1²+ x2²,+ x3²
y = x.pow(2).sum() 
# 進行反向傳播,計算梯度 x`的梯度,它對應於函式 f(x1,x2,x3)= x1²+ x2²+ x3², 三個偏導數就是 2x1,2x2,2x3,帶入tensor的值 即'[2x1,2x2,2x3]
y.backward() 
# 輸出 x 的梯度
print(x.grad)  # 輸出 tensor([2., 4., 6.])
print("===========requires_grad 例子3============")
# 建立一個張量,並指定需要計算梯度
x = torch.tensor([[1.0, 2.0],[4.0, 5.0]], requires_grad=True) 
# 定義一個標量函式 平方在求和 相當於函式 f()= x1²+ x2²+ x3²+ x4²
y = x.pow(2).sum() 
# 進行反向傳播,計算梯度 x`的梯度,這裡是2*2矩陣,但計算的時候,就按元素個數算x,沒有行列ij。
# 它對應於函式 f(x1,x2,x3,x4)= x1²+ x2²,+ x3²+ x4², 四個偏導數就是 2x1,2x2,2x3,2x4,帶入tensor的值 即'[2x1,2x2,2x4,2x5]
y.backward() 
# 輸出 x 的梯度
print(x.grad)  # 輸出 tensor([[2, 4][8,10]])

基礎學習就先到這。


注:此文章為原創,任何形式的轉載都請聯絡作者獲得授權並註明出處!



若您覺得這篇文章還不錯,請點選下方的【推薦】,非常感謝!

https://www.cnblogs.com/kiba/p/18346596

相關文章