臺大2020年深度學習課程作業二(搬運)

qq_長期不在發表於2020-11-09

臺大2020年深度學習課程作業二(搬運)

厚顏無恥的搬運一下,方便不能翻牆的小夥伴查閱。

import numpy as np
import matplotlib.pyplot as plt

X_test_path='./data/X_test'
X_train_path='./data/X_train'
Y_train_path='./data/Y_train'
with open(X_test_path) as f:
    next(f)
    X_test=np.array([line.strip('\n').split(',')[1:] for line in f],dtype=float)
with open(X_train_path) as f:
    next(f)
    X_train=np.array([line.strip('\n').split(',')[1:] for line in f],dtype=float)
with open(Y_train_path) as f:
    next(f)
    Y_train=np.array([line.strip('\n').split(',')[1:] for line in f],dtype=float)

#訓練資料和測試資料的歸一化操作
def _normalization(X,train=True,cloumn_index=None,X_mean=None,X_std=None):
    if cloumn_index==None:
        cloumn_index=np.arange(len(X[0]))  
    if train:
        X_mean=np.mean(X[:,cloumn_index],axis=0)
        X_std=np.std(X[:,cloumn_index],axis=0)
    X[:,cloumn_index]=(X[:,cloumn_index]-X_mean)/(X_std+1e-8)
    return X,X_mean,X_std
X_train,X_mean,X_std=_normalization(X_train)
X_test,_,_=_normalization(X_test,False,None,X_mean,X_std)    

#劃分訓練集和驗證集
def _splitdata(X,Y,split_ratio=0.2):
    splitIndex=int(X.shape[0]*(1-split_ratio))
    return X[:splitIndex],Y[:splitIndex],X[splitIndex:],Y[splitIndex:]
dev_ratio=0.1
X_train,Y_train,X_dev,Y_dev=_splitdata(X_train,Y_train,0.1)

train_size = X_train.shape[0]
dev_size = X_dev.shape[0]
test_size = X_test.shape[0]
data_dim = X_train.shape[1]
print('Size of training set: {}'.format(train_size))
print('Size of development set: {}'.format(dev_size))
print('Size of testing set: {}'.format(test_size))
print('Dimension of data: {}'.format(data_dim))

#隨機函式
def _shuffle(X,Y):
    randomIndex=np.random.shuffle(np.arange(X.shape[0]))
    return X[randomIndex],Y[randomIndex]
#啟用函式
def _sigmoid(Z):
    return np.clip(1/(1-np.exp(-Z)),1e-8,1-1e-18)
#神經元前向函式
def _f(X,w,b):
    return _sigmoid(np.matmul(X,w)+b)
#預測函式
def _prediction(X,w,b):
    return np.round(_f(X,w,b)).astype(np.int)
#精度判斷函式
def _accuracy(Y_pred,Y_label):
    return 1-np.mean(np.abs(Y_pred-Y_label))

#交叉熵函式
def _cross_entropy_loss(Y_pred,Y_label):
    loss=-(np.dot(Y_label,np.log(Y_pred))+np.dot(1-Y_label,np.log(1-Y_pred)))
    return loss
#梯度函式
def _gradient(X,Y_label,w,b):
    Y_pred=_prediction(X,w,b)
    loss=(Y_label-Y_pred)
    w_grad=-np.sum(loss*X.T,1)
    b_grad=-np.sum(loss)
    return w_grad,b_grad

#引數初始化
w=np.zeros((data_dim,))
b=np.ones((1,))

max_iter=10
bachsize=8
learning_rate=0.2
step=1#用於標記學習率的衰減

#訓練時儲存的引數
train_loss=[]
dev_loss=[]
train_acu=[]
dev_acu=[]

#開始進行模型訓練
for epoch in range(max_iter):
    X_train,Y_train=_shuffle(X_train,Y_train)
    for idx in range(int(np.floor(train_size/bachsize))):
        X_batch=X_train[idx*bachsize:(idx+1)*bachsize]
        Y_batch=Y_train[idx*bachsize:(idx+1)*bachsize]
        w_grad,b_grad=_gradient(X_batch,Y_batch,w,b)
        w=w-learning_rate/sqrt(step)*w_grad
        b=b-learning_rate/sqrt(step)*b_grad
        step+=1
    train_predict=np.floor(_f(X_train,w,b))
    train_acu.append(_accuracy(train_predict,Y_train))
    train_loss.append(_cross_entropy_loss(train_predict,Y_train)/train_size)
    
    dev_prediction=np.floor(_f(X_dev,w,b))
    dev_acu.append(_accuracy(dev_prediction,Y_dev))
    train_loss.append(_cross_entropy_loss(dev_prediction,Y_dev)/dev_size)
print('Training loss: {}'.format(train_loss[-1]))
print('Development loss: {}'.format(dev_loss[-1]))
print('Training accuracy: {}'.format(train_acc[-1]))
print('Development accuracy: {}'.format(dev_acc[-1]))

課程連結

相關文章