小白學習之pytorch框架(7)之實戰Kaggle比賽:房價預測(K折交叉驗證、*args、**kwargs)


本篇博客代碼來自於《動手學深度學習》pytorch版,也是代碼較多,解釋較少的一篇。不過好多方法在我以前的博客都有提,所以這次沒提。還有一個原因是,這篇博客的代碼,只要好好看看肯定能看懂(前提是python語法大概了解),這是我不加很多解釋的重要原因。

K折交叉驗證實現

def get_k_fold_data(k, i, X, y):
    # 返回第i折交叉驗證時所需要的訓練和驗證數據,分開放,X_train為訓練數據,X_valid為驗證數據
    assert k > 1
    fold_size = X.shape[0] // k  # 雙斜杠表示除完后再向下取整
    X_train, y_train = None, None
    for j in range(k):
        idx = slice(j * fold_size, (j + 1) * fold_size)  #slice(start,end,step)切片函數
        X_part, y_part = X[idx, :], y[idx]
        if j == i:
            X_valid, y_valid = X_part, y_part
        elif X_train is None:
            X_train, y_train = X_part, y_part
        else:
            X_train = torch.cat((X_train, X_part), dim=0) #dim=0增加行數,豎着連接
            y_train = torch.cat((y_train, y_part), dim=0)
    return X_train, y_train, X_valid, y_valid

def k_fold(k, X_train, y_train, num_epochs,learning_rate, weight_decay, batch_size):
    train_l_sum, valid_l_sum = 0, 0
    for i in range(k):
        data = get_k_fold_data(k, i, X_train, y_train) # 獲取k折交叉驗證的訓練和驗證數據
        net = get_net(X_train.shape[1])  #get_net在這是一個基本的線性回歸模型,方法實現見附錄1
        train_ls, valid_ls = train(net, *data, num_epochs, learning_rate,
                                   weight_decay, batch_size)  #train方法見后面附錄2
        train_l_sum += train_ls[-1]
        valid_l_sum += valid_ls[-1]
        if i == 0:
            d2l.semilogy(range(1, num_epochs + 1), train_ls, 'epochs', 'rmse',
                         range(1, num_epochs + 1), valid_ls,
                         ['train', 'valid'])   #畫圖,且是對y求對數了,x未變。方法實現見附錄3
        print('fold %d, train rmse %f, valid rmse %f' % (i, train_ls[-1], valid_ls[-1]))
    return train_l_sum / k, valid_l_sum / k

 *args:表示接受任意長度的參數,然后存放入一個元組中;如def fun(*args) print(args),‘fruit','animal','human'作為參數傳進去,輸出(‘fruit','animal','human')

**kwargs:表示接受任意長的參數,然后存放入一個字典中;如

def fun(**kwargs):   
    for key, value in kwargs.items():
        print("%s:%s" % (key,value)

fun(a=1,b=2,c=3)會輸出 a=1 b=2 c=3

附錄1

loss = torch.nn.MSELoss()

def get_net(feature_num):
    net = nn.Linear(feature_num, 1)
    for param in net.parameters():
        nn.init.normal_(param, mean=0, std=0.01) 
    return net

附錄2

def train(net, train_features, train_labels, test_features, test_labels, num_epochs, learning_rate,weight_decay, batch_size):
    train_ls, test_ls = [], []
    dataset = torch.utils.data.TensorDataset(train_features, train_labels)
    train_iter = torch.utils.data.DataLoader(dataset, batch_size, shuffle=True) #TensorDataset和DataLoader的使用請查看我以前的博客
    
    #這里使用了Adam優化算法
    optimizer = torch.optim.Adam(params=net.parameters(), lr= learning_rate, weight_decay=weight_decay)
    net = net.float()
    for epoch in range(num_epochs):
        for X, y in train_iter:
            l = loss(net(X.float()), y.float())
            optimizer.zero_grad()
            l.backward()
            optimizer.step()
        train_ls.append(log_rmse(net, train_features, train_labels))
        if test_labels is not None:
            test_ls.append(log_rmse(net, test_features, test_labels))
    return train_ls, test_ls

 附錄3

def semilogy(x_vals, y_vals, x_label, y_label, x2_vals=None, y2_vals=None, legend=None, figsize=(3.5, 2.5)):
    set_figsize(figsize)
    plt.xlabel(x_label)
    plt.ylabel(y_label)
    plt.semilogy(x_vals, y_vals)
    if x2_vals and y2_vals:
        plt.semilogy(x2_vals, y2_vals, linestyle=':')
        plt.legend(legend)

 注:由於最近有其他任務,所以此博客寫的匆忙,等我有時間后會豐富,也可能加詳細解釋。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM