tensorflow, pytorch,loss可視化畫圖模板代碼(推薦)


重要的幾段代碼摘抄如下:

import matplotlib.pyplot as plt

yy_train_loss = []
yy_valid_loss = []
yy_train_acc = []
yy_valid_acc = []
xx = []

#def train 或 def fit:
    for epoch in range(epochs):
            xx.append(epoch)
            yy_train_loss.append(total_loss / len(loader_train))
            yy_train_acc.append( train_acc  )
    
    #valid:
    yy_valid_loss.append(total_loss / len(loader))
    yy_valid_acc.append(val_gini_score)

#可視化並且保存
#def plot_png():
ax1 = plt.subplot(1, 2, 1) plt.sca(ax1) plt.plot(xx, yy_train_loss, "r", label="train_logloss") plt.plot(xx, yy_valid_loss, "b", label="valid_logloss") plt.legend() ax2 = plt.subplot(1, 2, 2) plt.sca(ax2) plt.plot(xx, yy_train_acc, "y", label="train_acc") plt.plot(xx, yy_valid_acc, "g", label="valid_norm_gini") plt.legend() plt.savefig("./loss.png") print("保存了loss.png") print("over!")

 

 

給一個DeepFM.py完整文件

# -*- coding: utf-8 -*-

"""
A pytorch implementation of DeepFM for rates prediction problem.
"""
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import matplotlib.pyplot as plt
import os
from metrics import gini_norm

import sys
import torch.optim as optim

import time

yy_train_loss = []
yy_valid_loss = []
yy_train_acc = []
yy_valid_acc = []
xx = []
best_acc = 0
best_gini_score = 0        # gini越大越好

criterion = F.binary_cross_entropy_with_logits  #相當於logloss  ,這里自己修改,改成自定義的gini系數

class DeepFM(nn.Module):
    """
    A DeepFM network with RMSE loss for rates prediction problem.

    There are two parts in the architecture of this network: fm part for low
    order interactions of features and deep part for higher order. In this 
    network, we use bachnorm and dropout technology for all hidden layers,
    and "Adam" method for optimazation.

    You may find more details in this paper:
    DeepFM: A Factorization-Machine based Neural Network for CTR Prediction,
    Huifeng Guo, Ruiming Tang, Yunming Yey, Zhenguo Li, Xiuqiang He.
    """

    def __init__(self, feature_sizes, embedding_size=8,
                 hidden_dims=[32, 32], num_classes=1, dropout=[0.5, 0.5], 
                 use_cuda=True, verbose=False):
        """
        Initialize a new network

        Inputs: 
        - feature_size: A list of integer giving the size of features for each field.
        - embedding_size: An integer giving size of feature embedding.
        - hidden_dims: A list of integer giving the size of each hidden layer.
        - num_classes: An integer giving the number of classes to predict. For example,
                    someone may rate 1,2,3,4 or 5 stars to a film.
        - batch_size: An integer giving size of instances used in each interation.
        - use_cuda: Bool, Using cuda or not
        - verbose: Bool
        """
        super().__init__()
        self.field_size = len(feature_sizes)
        self.feature_sizes = feature_sizes
        self.embedding_size = embedding_size
        self.hidden_dims = hidden_dims
        self.num_classes = num_classes
        self.dtype = torch.long
        self.bias = torch.nn.Parameter(torch.randn(1))
        """
            check if use cuda
        """
        if use_cuda and torch.cuda.is_available():
            self.device = torch.device('cuda')
        else:
            self.device = torch.device('cpu')
        """
            init fm part
        """
        self.fm_first_order_embeddings = nn.ModuleList(
            [nn.Embedding(feature_size, 1) for feature_size in self.feature_sizes])
        self.fm_second_order_embeddings = nn.ModuleList(
            [nn.Embedding(feature_size, self.embedding_size) for feature_size in self.feature_sizes])
        """
            init deep part
        """
        all_dims = [self.field_size * self.embedding_size] + \
            self.hidden_dims + [self.num_classes]  #形如[k,h1,h2,1] , hidden_dims是[32,32]
        for i in range(1, len(hidden_dims) + 1):
            setattr(self, 'linear_'+str(i),                 # 新方法,setattr設置object的屬性時,屬性不一定存在
                    nn.Linear(all_dims[i-1], all_dims[i]))
            # nn.init.kaiming_normal_(self.fc1.weight)
            setattr(self, 'batchNorm_' + str(i),
                    nn.BatchNorm1d(all_dims[i]))
            setattr(self, 'dropout_'+str(i),
                    nn.Dropout(dropout[i-1]))

    def forward(self, Xi, Xv):
        """
        Forward process of network. 

        Inputs:
        - Xi: A tensor of input's index, shape of (N, field_size, 1)  #注意!這里因為是一個batch,所以是三維的
        - Xv: A tensor of input's value, shape of (N, field_size)   # modified,原文寫錯了點,這里是二維
        """
        """
            fm part
        """
        # Xv[:, i]) 維度是(100,)

        # test code
        # for i,emb in enumerate(self.fm_first_order_embeddings):
        #     print("i:",i)
        #     print("emb:",emb)
        #     print("Xi.shape:",Xi.shape)
        #     print("Xi:",Xi)
        #     print("Xi[:,i,:]:", Xi[:,i,:])

        fm_first_order_emb_arr = [(torch.sum(emb(Xi[:, i, :]), 1).t() * Xv[:, i]).t() for i, emb in enumerate(self.fm_first_order_embeddings)]
        fm_first_order = torch.cat(fm_first_order_emb_arr, 1)  # 100*39
        fm_second_order_emb_arr = [(torch.sum(emb(Xi[:, i, :]), 1).t() * Xv[:, i]).t() for i, emb in enumerate(self.fm_second_order_embeddings)]
        # fm_second_order_emb_arr: [N*k, N*k, ...]
        fm_sum_second_order_emb = sum(fm_second_order_emb_arr)
        fm_sum_second_order_emb_square = fm_sum_second_order_emb * \
            fm_sum_second_order_emb  # (x+y)^2
        fm_second_order_emb_square = [
            item*item for item in fm_second_order_emb_arr]
        fm_second_order_emb_square_sum = sum(
            fm_second_order_emb_square)  # x^2+y^2
        fm_second_order = (fm_sum_second_order_emb_square -
                           fm_second_order_emb_square_sum) * 0.5
        """
            deep part
        """
        deep_emb = torch.cat(fm_second_order_emb_arr, 1)  #按照列方向進行拼接
        deep_out = deep_emb
        for i in range(1, len(self.hidden_dims) + 1):
            deep_out = getattr(self, 'linear_' + str(i))(deep_out)
            deep_out = getattr(self, 'batchNorm_' + str(i))(deep_out)
            deep_out = getattr(self, 'dropout_' + str(i))(deep_out)
        """
            sum
        """
        total_sum = torch.sum(fm_first_order, 1) + \
                    torch.sum(fm_second_order, 1) + torch.sum(deep_out, 1) + self.bias
        return total_sum

    def fit(self, loader_train, loader_val, optimizer, epochs=100, verbose=False, print_every=100):
        """
        Training a model and valid accuracy.

        Inputs:
        - loader_train: I
        - loader_val: .
        - optimizer: Abstraction of optimizer used in training process, e.g., "torch.optim.Adam()""torch.optim.SGD()".
        - epochs: Integer, number of epochs.
        - verbose: Bool, if print.
        - print_every: Integer, print after every number of iterations. 
        """
        """
            load input data
        """
        model = self.train().to(device=self.device)


        for epoch in range(epochs):
            #global s_time, e_time
            s_time = time.time()
            
            xx.append(epoch)
            train_num_correct = 0
            train_num_samples = 0
            total_loss = 0
            train_acc = 0
            all_gini_score = 0

            for t, (xi, xv, y) in enumerate(loader_train):
                xi = xi.to(device=self.device, dtype=self.dtype)
                xv = xv.to(device=self.device, dtype=torch.float)
                y = y.to(device=self.device, dtype=torch.float)
                
                total = model(xi, xv)  # 回到forward函數 , 返回 100*1維
                loss = criterion(total, y)  # y是label,整型 0或1

                #preds_prob = F.sigmoid(total)
                #gini_score = gini_norm(y, preds_prob)   # actual/pred

                #gini_score = gini_norm(y.cuda().data.cpu().numpy(), preds_prob.cuda().data.cpu().numpy())

                #all_gini_score += gini_score
                # print("type(all_gini_score):",type(all_gini_score))
                # print("all_gini_score/len(loader_train):",all_gini_score/len(loader_train))

                preds = (F.sigmoid(total) > 0.5)  # 配合sigmoid使用
                train_num_correct += (preds == y).sum()
                train_num_samples += preds.size(0)  # 每次加上一個batch_size
                total_loss += loss.item()

                optimizer.zero_grad()
                loss.backward()
                optimizer.step()

                train_acc = float(train_num_correct) / train_num_samples
                #print('Got Train %d / %d correct (%.2f%%)' % (train_num_correct, train_num_samples, 100 * train_acc))

                print('[ Epoch{}: {}/{} ] loss:{:.3f} acc:{:.3f} '.format(epoch + 1, t + 1, len(loader_train), loss.item(), train_acc *100), end='\r')

                # print('[ Epoch{}: {}/{} ] loss:{:.3f} gini_score:{:.4f} '.format(
                #          epoch + 1, t + 1, len(loader_train), loss.item(), all_gini_score / (t+1)), end='\r')
            e_time = time.time()
            print("epoch:{} cost time:{} minutes:".format(epoch, (e_time-s_time)/60 ))
            print('\nTrain | Loss:{:.5f} acc: {:.3f}'.format(total_loss / len(loader_train), train_acc  ))
            yy_train_loss.append(total_loss / len(loader_train))
            yy_train_acc.append( train_acc  )

            #if verbose and t % print_every == 0:             #修改源代碼,減少一個tab
           # if verbose:
                #print('Iteration %d, loss = %.4f' % (t, loss.item()))
            self.check_accuracy(loader_val, model)

        #end of epoch loop

        ax1 = plt.subplot(1, 2, 1)
        plt.sca(ax1)
        plt.plot(xx, yy_train_loss, "r", label="train_logloss")
        plt.plot(xx, yy_valid_loss, "b", label="valid_logloss")
        plt.legend()
        ax2 = plt.subplot(1, 2, 2)
        plt.sca(ax2)
        plt.plot(xx, yy_train_acc, "y", label="train_acc")
        plt.plot(xx, yy_valid_acc, "g", label="valid_norm_gini")
        plt.legend()

        plt.savefig("./loss.png")
        print("保存了loss.png和model_save/best_ckpt.model")
        print("model.fit() over!")
    
    def check_accuracy(self, loader, model):
#         if loader.dataset.train:
#             print('Checking accuracy on validation set')
#         else:
#             print('Checking accuracy on test set')   
        num_correct = 0
        num_samples = 0
        model.eval()  # set model to evaluation mode
        with torch.no_grad():
            total_loss = 0
            all_gini_score = 0
            pred_gini = []
            actual = []
            for t,(xi, xv, y) in enumerate(loader):
                xi = xi.to(device=self.device, dtype=self.dtype)  # move to device, e.g. GPU
                xv = xv.to(device=self.device, dtype=torch.float)
                y = y.to(device=self.device, dtype=torch.float)

                total = model(xi, xv)

                loss = criterion(total, y)

                preds_prob = F.sigmoid(total)
                #gini_score = gini_norm(y, preds_prob)  # actual/pred
                # gini_score = gini_norm(y.cuda().data.cpu().numpy(), preds_prob.cuda().data.cpu().numpy())
                #print("type(y.cuda().data.cpu().numpy()):",type(y.cuda().data.cpu().numpy()) )
                actual = np.append(actual , y.cuda().data.cpu().numpy())
                pred_gini = np.append(pred_gini , preds_prob.cuda().data.cpu().numpy())
                
                # all_gini_score += gini_score


                total_loss += loss.item()

                y = y.to(device=self.device, dtype=torch.bool)
                preds = (F.sigmoid(total) > 0.5)  #配合sigmoid使用
                num_correct += (preds == y).sum()
                num_samples += preds.size(0)  #每次加上一個batch_size
            valid_acc = float(num_correct) / num_samples
            
            
            
            val_gini_score = gini_norm(actual, pred_gini)
            # exit(0)

           # print("valid norm gini:", val_gini_score)

            #print('Got Valid %d / %d correct (%.2f%%)' % (num_correct, num_samples, 100 * acc))
            print("Valid | Loss:{:.5f} norm_gini:{}".format(total_loss / len(loader), val_gini_score ))

            yy_valid_loss.append(total_loss / len(loader))
            yy_valid_acc.append(val_gini_score)
            if(not os.path.exists("model_save")):
                    os.mkdir("model_save")
                    
            torch.save(model, "model_save/final_ckpt.model") # best_ckpt.model 和test.ipynb文件保持一致才行
            
            global best_gini_score
            if val_gini_score  > best_gini_score:

                # 如果validation的結果優於之前所有的結果,就把當下的模型存下來以備之後做預測時使用
                best_gini_score = val_gini_score
                if(not os.path.exists("model_save")):
                    os.mkdir("model_save")
                torch.save(model, "model_save/best_ckpt.model") # best_ckpt.model 和test.ipynb文件保持一致才行




                        

 


免責聲明!

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



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