《AI時代:碼農的涅盤重生》第60章 第一個模型(1)

作者:Flint8·7天前

深夜十一點,狹窄的書房裡,只有書桌上的螢幕還亮著。

林晨盯著PyTorch官方教程的最後一個章節,已經看了三遍。螢幕上是一個完整的神經網路程式碼示例——IST手寫數字識別,深度學習界的“Hello World”。過去兩週,他像海綿一樣吸收著那些抽象的概念:張量、梯度、反向傳播、損失函式。數學補課起了作用,至少現在看到矩陣乘法不再發怵,能理解為什麼權重更新要用鏈式法則。但理解歸理解,距離“親手創造一個能思考的東西”,還隔著一段需要程式碼去填補的距離。

“跟著做一遍”。他對自己說,聲音在安靜的房間裡顯得格外清晰。新建Python檔案,匯入torch和torchvision。下載IST資料集——一個包含六萬張28x28畫素手寫數字圖片的經典資料集。程式碼跑起來,終端開始顯示下載進度。

林晨看著那些滾動的日誌,忽然有些恍惚。三十五歲,再次失業1個月,存款以每月兩萬多的速度消耗,自己卻在這裡下載一堆黑白數字圖片。這個場景如果拍下來給一年前的自己看,恐怕會覺得是個荒誕的玩笑。但資料下載完成的提示音把他拉回現實。

接下來是資料預處理:將圖片畫素值從0-255歸一化到0-1之間,轉換成PyTorch能處理的Tensor格式,分割成訓練集和測試集。這些步驟他已經在Jupyter Notebook裡練習過多次,手指在鍵盤上敲擊得流暢。真正的挑戰從定義模型開始。

教程提供了一個簡單的全連線神經網路:輸入層784個節點(28x28),兩個隱藏層各128個節點,輸出層10個節點(對應數字0-9)。結構圖在螢幕上展開,林晨逐行敲入程式碼。

class Net(nn.dule):

def __init__(self):

super(Net, self).__init__

self.fc1 = nn.Linear(784, 128)

self.fc2 = nn.Linear(128, 128)

self.fc3 = nn.Linear(128, 10)

def forward(self, x):

x = x.view(-1, 784)

x = F.relu(self.fc1(x))

x = F.relu(self.fc2(x))

x = self.fc3(x)

return x

不到二十行程式碼。但林晨知道,這二十行背後是三十年來神經網路研究的結晶。每一層Linear代表一次矩陣乘法和偏置加法,每個ReLU啟用函式給模型注入非線性——正是這種非線性讓神經網路能夠擬合複雜的函式關係。

他想起大學時上的《人工智慧導論》,教授說神經網路是“黑箱”,輸入輸出之間是難以解釋的權重迷宮。當時覺得神秘,現在親手搭建時,卻感受到一種奇異的透明感——每一層都在做確定性的數學運算,所謂的“智慧”不過是這些運算在大量資料訓練後,權重被調整到能提取有效特徵的狀態。

“程式碼可以騙人,但邏輯不會”。他低聲念著自己的口頭禪,點選執行。

模型初始化完成。接下來是訓練迴圈的核心部分:定義損失函式(交叉熵損失)和最佳化器(隨機梯度下降SGD)。學習率設為0.01,一個保守的起始值。第一次訓練開始了。

林晨設定了5個epoch(遍歷整個訓練集的次數)。程式碼執行,GPU風扇輕微轉動——他慶幸自己當年配電腦時選了帶獨立顯示卡的型號,雖然是為了打遊戲,現在卻成了訓練模型的利器。

第一個epoch結束時,終端打印出損失值:2.302。準確率:10.3%。“跟隨機猜差不多”。林晨苦笑。IST有十個類別,隨機猜測的準確率應該是10%,模型現在幾乎沒學到任何東西。

但他沒有停。第二個epoch,損失降到1.876,準確率升到23.7%。第三個epoch,1.432,45.2%。數字的變化有種催眠般的魔力,他盯著螢幕,看著那些代表模型正在“學習”的證據。第四個epoch結束時,準確率突破了70%。損失值降到0.876。

林晨身體前傾,手肘撐在桌上。他能感覺到心跳在加速——不是因為緊張,而是因為某種接近真相的興奮。那些抽象的數學概念正在轉化為具體的、可測量的能力提升。模型在“理解”那些手寫數字的形狀特徵。

第五個epoch,最後一個。訓練迴圈在執行,進度條緩慢移動。林晨起身倒了杯水,回到座位時,剛好看到最終結果打印出來:Epoch 5/5, Loss: 0.356, Accuracy: 89.7%。

猜你喜歡

同題材或同分類的其他作品。