import torch
from IPython import display
from d2l import torch as d2l
batch_size= 256
train_iter, test_iter= d2l. load_data_fashion_mnist( batch_size)
num_inputs= 784
num_outputs= 10
w= torch. normal( 0 , 0.01 , size= ( num_inputs, num_outputs) , requires_grad= True )
b= torch. zeros( num_outputs, requires_grad= True )
X= torch. tensor( [ [ 1.0 , 2.0 , 3.0 ] , [ 4.0 , 5.0 , 6.0 ] ] )
X. sum ( 0 , keepdim= True ) , X. sum ( 1 , keepdim= True )
def softmax ( X) :
X_exp = torch. exp( X)
partition = X_exp. sum ( 1 , keepdims= True )
return X_exp / partition
X= torch. normal( 0 , 1 , ( 2 , 5 ) )
X_prob= softmax( X)
X_prob, X_prob. sum ( 1 )
def net ( X) :
return softmax( torch. matmul( X. reshape( ( - 1 , w. shape[ 0 ] ) ) , w) + b)
y= torch. tensor( [ 0 , 2 ] )
y_hat= torch. tensor( [ [ 0.1 , 0.3 , 0.6 ] , [ 0.3 , 0.2 , 0.5 ] ] )
y_hat[ [ 0 , 1 ] , y]
def cross_entropy ( y_hat, y) :
return - torch. log( y_hat[ range ( len ( y_hat) ) , y] )
cross_entropy( y_hat, y)
def accuracy ( y_hat, y) :
"""
计算预测正确的数量
"""
if len ( y_hat. shape) > 1 and y_hat. shape[ 1 ] > 1 :
y_hat= y_hat. argmax( axis= 1 )
cmp = y_hat. type ( y. dtype) == y
return float ( cmp . type ( y. dtype) . sum ( ) )
accuracy( y_hat, y) / len ( y)
def evaluate_accuracy ( net, data_iter) :
"""计算在指定数据集上模型的精度。"""
if isinstance ( net, torch. nn. Module) :
net. eval ( )
metric = Accumulator( 2 )
for X, y in data_iter :
metric. add( accuracy( net( X) , y) , y. numel( ) )
return metric[ 0 ] / metric[ 1 ]
class Accumulator :
"在n个变量上累加。" ""
def _init_ ( self, n) :
self. data = [ 0.0 ] * n
def add ( self, * args) :
self. data = [ a + float ( b) for a, b in zip ( self. data, args) ]
def reset ( self) :
self. data = [ 0.0 ] * len ( self. data)
def _getitem__ ( self, idx) :
return self. data[ idx]
evaluate_accuracy( net, test_iter)
def train_epoch_ch3 ( net, train_iter, loss, updater) :
if isinstance ( net, torch. nn. Module) :
net. train( )
metric = Accumulator( 3 )
for X, y in train_iter:
y_hat = net( X)
l = loss( y_hat, y)
if isinstance ( updater, torch. optim. optimizer) :
updater. zero_grad( )
l. backward( )
updater. step( )
metric. add(
float ( l) * len ( y) , accuracy( y_hat, y) ,
y. size( ) . numel( ) )
else :
l. sum ( ) . backward( )
updater( X. shape[ 0 ] )
metric. add( float ( l. sum ( ) ) , accuracy( y_hat, y) , y. numel( ) )
return metric[ 0 ] / metric[ 2 ] , metric[ 1 ] / metric[ 2 ]
def train_ch3 ( net, train_iter, test_iter, loss, num_epochs, updater) :
animator = Animator ( xlabel= 'epoch' , xlim= [ 1 , num_epochs] , ylim= [ 0.3 ] ,
legend= [ ' train loss' , 'train acc' , 'test acc' ] )
for epoch in range ( num_epochs) :
train_metrics = train_epoch_ch3( net, train_iter, loss, updater)
test_acc = evaluate_accuracy( net, test_iter)
animator. add( epoch + 1 , train_metrics + ( test_acc) )
train_loss, train_acc = train_metrics
num_epochs= 10
train_ch3( net, train_iter, test_iter, cross_entropy, num_epochs, updater= True )