日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

DeepCross(DCN)模型及torch实现

發布時間:2023/12/16 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 DeepCross(DCN)模型及torch实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、前言

模型針對W&D的wide部分進行了改進, 因為Wide部分有一個不足就是需要人工進行特征的組合篩選, 過程繁瑣且需要經驗, 2階的FM模型在線性的時間復雜度中自動進行特征交互,但是這些特征交互的表現能力并不夠,并且隨著階數的上升,模型復雜度會大幅度提高。于是乎,作者用一個Cross Network替換掉了Wide部分,來自動進行特征之間的交叉,并且網絡的時間和空間復雜度都是線性的。 通過與Deep部分相結合,構成了深度交叉網絡(Deep & Cross Network),簡稱DCN。

二、Deep&Cross模型

下面就來看一下DCN的結構:模型的結構非常簡潔,從下往上依次為:Embedding和Stacking層、Cross網絡層與Deep網絡層并列、輸出合并層,得到最終的預測結果。

?(1)Embedding and stacking layer

這里的作用依然是把稀疏離散的類別型特征變成低維密集型。

運用起來就是在訓練得到的Embedding參數矩陣中找到屬于當前樣本對應的Embedding向量

最后,該層需要將所有的密集型特征與通過embedding轉換后的特征進行聯合(Stacking)

?(2) Cross Network

設計該網絡的目的是增加特征之間的交互力度。 交叉網絡由多個交叉層組成

?交叉層的操作的二階部分非常類似PNN提到的外積操作, 在此基礎上增加了外積操作的權重向量, 以及原輸入向量和偏置向量。 交叉層的可視化如下:

?代碼實現部分對應

# x是(None, dim)的形狀, 先擴展一個維度到(None, dim, 1)x_0 = torch.unsqueeze(x, dim=2)x = x_0.clone() #32*221*1xT = x_0.clone().permute((0, 2, 1)) # (None, 1, dim) 32*1*221for i in range(self.layer_num):x = torch.matmul(torch.bmm(x_0, xT), self.cross_weights[i]) + self.cross_bias[i] + x # (None, dim, 1)32*221*1 bmm(32*221*1,32*1*221), W=221*1, b=221*1xT = x.clone().permute((0, 2, 1)) # (None, 1, dim)

?是最開始的輸入,一直保持不變,是不斷更新的,與權重+偏差 做內積

并且在每一層均保留了輸入向量, 因此輸入和輸出之間的變化不會特別明顯。

(3)Deep work

全連接層原理一樣。

?(4)組合層

負責將兩個網絡的輸出進行拼接, 并且通過簡單的Logistics回歸完成最后的預測:

?

最后二分類的損失函數依然是交叉熵損失:

?其核心部分就是Cross Network, 這個可以進行特征的自動交叉, 避免了更多基于業務理解的人工特征組合。 該模型相比于W&D,Cross部分表達能力更強, 使得模型具備了更強的非線性學習能力。

三、Deep&Cross模型的pytorch實現

(1)DNN網絡

class Dnn(nn.Module):"""Dnn part"""def __init__(self, hidden_units, dropout=0.):"""hidden_units: 列表, 每個元素表示每一層的神經單元個數, 比如[256, 128, 64], 兩層網絡, 第一層神經單元128, 第二層64, 第一個維度是輸入維度dropout: 失活率"""super(Dnn, self).__init__()self.dnn_network = nn.ModuleList([nn.Linear(layer[0], layer[1]) for layer in list(zip(hidden_units[:-1], hidden_units[1:]))]) #221*128*64self.dropout = nn.Dropout(p=dropout)def forward(self, x):for linear in self.dnn_network:x = linear(x)x = F.relu(x)x = self.dropout(x)return x

(2)cross_network

class CrossNetwork(nn.Module):"""Cross Network"""def __init__(self, layer_num, input_dim):super(CrossNetwork, self).__init__()self.layer_num = layer_num# 定義網絡層的參數 221*3 三個self.cross_weights = nn.ParameterList([nn.Parameter(torch.rand(input_dim, 1))for i in range(self.layer_num)])self.cross_bias = nn.ParameterList([nn.Parameter(torch.rand(input_dim, 1))for i in range(self.layer_num)])def forward(self, x):# x是(None, dim)的形狀, 先擴展一個維度到(None, dim, 1)x_0 = torch.unsqueeze(x, dim=2)x = x_0.clone() #32*221*1xT = x_0.clone().permute((0, 2, 1)) # (None, 1, dim) 32*1*221for i in range(self.layer_num):x = torch.matmul(torch.bmm(x_0, xT), self.cross_weights[i]) + self.cross_bias[i] + x # (None, dim, 1)32*221*1 bmm(32*221*1,32*1*221), W=221*1, b=221*1xT = x.clone().permute((0, 2, 1)) # (None, 1, dim)x = torch.squeeze(x) # (None, dim) 32*221 再降維return x

?(3)DCN網絡

class DCN(nn.Module):def __init__(self, feature_columns, hidden_units, layer_num, dnn_dropout=0.):super(DCN, self).__init__()self.dense_feature_cols, self.sparse_feature_cols = feature_columns# embeddingself.embed_layers = nn.ModuleDict({'embed_' + str(i): nn.Embedding(num_embeddings=feat['feat_num'], embedding_dim=feat['embed_dim'])for i, feat in enumerate(self.sparse_feature_cols)})hidden_units.insert(0,len(self.dense_feature_cols) + len(self.sparse_feature_cols) * self.sparse_feature_cols[0]['embed_dim'])self.dnn_network = Dnn(hidden_units)self.cross_network = CrossNetwork(layer_num, hidden_units[0]) # layer_num是交叉網絡的層數, hidden_units[0]表示輸入的整體維度大小self.final_linear = nn.Linear(hidden_units[-1] + hidden_units[0], 1)def forward(self, x):dense_input, sparse_inputs = x[:, :len(self.dense_feature_cols)], x[:, len(self.dense_feature_cols):] #32*13 32*26sparse_inputs = sparse_inputs.long()sparse_embeds = [self.embed_layers['embed_' + str(i)](sparse_inputs[:, i]) for i inrange(sparse_inputs.shape[1])]sparse_embeds = torch.cat(sparse_embeds, axis=-1) #32*208 208=(26*8)x = torch.cat([sparse_embeds, dense_input], axis=-1) #32*221# cross Networkcross_out = self.cross_network(x) #32*221# Deep Networkdeep_out = self.dnn_network(x) #32*32# Concatenatetotal_x = torch.cat([cross_out, deep_out], axis=-1) #32*253# outoutputs = F.sigmoid(self.final_linear(total_x))return outputs

模型訓練

# 模型的相關設置 def auc(y_pred, y_true):pred = y_pred.datay = y_true.datareturn roc_auc_score(y, pred)loss_func = nn.BCELoss() optimizer = torch.optim.Adam(params=model.parameters(), lr=0.001) metric_func = auc metric_name = 'auc'# 腳本訓練風格 epochs = 10 log_step_freq = 10dfhistory = pd.DataFrame(columns=['epoch', 'loss', metric_name, 'val_loss', 'val_' + metric_name])print('start_training.........') nowtime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') print('========' * 8 + '%s' % nowtime)for epoch in range(1, epochs + 1):# 訓練階段model.train()loss_sum = 0.0metric_sum = 0.0step = 1for step, (features, labels) in enumerate(dl_train, 1):# 梯度清零optimizer.zero_grad()# 正向傳播predictions = model(features).squeeze()loss = loss_func(predictions, labels)try:metric = metric_func(predictions, labels)except ValueError:pass# 反向傳播loss.backward()optimizer.step()# 打印batch級別日志loss_sum += loss.item()metric_sum += metric.item()if step % log_step_freq == 0:print(("[step=%d] loss: %.3f, " + metric_name + ": %.3f") % (step, loss_sum / step, metric_sum / step));# 驗證階段model.eval()val_loss_sum = 0.0val_metric_sum = 0.0val_step = 1for val_step, (features, labels) in enumerate(dl_val, 1):with torch.no_grad():predictions = model(features).squeeze()val_loss = loss_func(predictions, labels)try:val_metric = metric_func(predictions, labels)except ValueError:passval_loss_sum += val_loss.item()val_metric_sum += val_metric.item()# 記錄日志info = (epoch, loss_sum / step, metric_sum / step, val_loss_sum / val_step, val_metric_sum / val_step)dfhistory.loc[epoch - 1] = info# 打印日志print(("\nEPOCH=%d, loss=%.3f, " + metric_name + " = %.3f, val_loss=%.3f, " + "val_" + metric_name + " = %.3f") % info)nowtime = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")print('\n' + '==========' * 8 + '%s' % nowtime)print('Finished Training')

測試集的預測

y_pred_probs = model(torch.tensor(test_x).float()) y_pred = torch.where(y_pred_probs>0.5, torch.ones_like(y_pred_probs), torch.zeros_like(y_pred_probs))print(y_pred.data)

?

?總結

W&D開啟了組合模型的探索之后,DCN也是替換掉了wide部分,?后面又出現了幾個FM的演化版本模型, 比如FNN, DeepFM和NFM, 后面也會陸續整理!!

?

總結

以上是生活随笔為你收集整理的DeepCross(DCN)模型及torch实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。