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文件保持一致才行