223 lines
9.5 KiB
Python
223 lines
9.5 KiB
Python
# 打印网络测试而已
|
||
import torch
|
||
import torch.nn as nn
|
||
from torch.nn.functional import normalize
|
||
|
||
|
||
class OneHotEncodingLayer(nn.Module):
|
||
def __init__(self, sz=256):
|
||
super(OneHotEncodingLayer, self).__init__()
|
||
self.size = sz
|
||
|
||
def forward(self, x):
|
||
return torch.nn.functional.one_hot(x, num_classes=self.size).float()
|
||
|
||
|
||
class ByteBlock(nn.Module):
|
||
def __init__(self, in_channels, nb_filter=(64, 100), filter_length=(3, 3),
|
||
subsample=(2, 1), pool_length=(2, 2)):
|
||
super(ByteBlock, self).__init__()
|
||
|
||
layers = []
|
||
for i in range(len(nb_filter)):
|
||
layers.append(nn.Conv1d(in_channels, nb_filter[i], kernel_size=filter_length[i],
|
||
padding=0, stride=subsample[i]))
|
||
layers.append(nn.Tanh())
|
||
if pool_length[i]:
|
||
layers.append(nn.MaxPool1d(pool_length[i]))
|
||
in_channels = nb_filter[i]
|
||
|
||
self.block = nn.Sequential(*layers)
|
||
self.global_pool = nn.AdaptiveMaxPool1d(1)
|
||
self.fc = nn.Linear(nb_filter[-1], 128)
|
||
|
||
def forward(self, x):
|
||
x = self.block(x)
|
||
x = self.global_pool(x).squeeze(dim=2)
|
||
x = torch.nn.functional.relu(self.fc(x))
|
||
return x
|
||
|
||
|
||
|
||
class FEMnet(nn.Module):
|
||
"""
|
||
Feature extraction module 定义
|
||
"""
|
||
def __init__(self, flow_len, packet_len, gru_units):
|
||
super(FEMnet, self).__init__()
|
||
self.packet_len = packet_len
|
||
self.flow_len = flow_len
|
||
self.batch_size = 10
|
||
self.gru_hidden_size = gru_units
|
||
self.rep_dim = gru_units
|
||
|
||
self.embedding = OneHotEncodingLayer(sz=256) # 独热编码
|
||
self.block2 = ByteBlock(self.packet_len, (128, 256), (5, 5), (1, 1), (2, 2))
|
||
self.block3 = ByteBlock(self.packet_len, (192, 320), (7, 5), (1, 1), (2, 2))
|
||
|
||
self.lstm_layer = nn.GRU(256, self.gru_hidden_size, dropout=0.1, bidirectional=True)
|
||
# self.dense_layer = nn.Linear(self.gru_hidden_size * 2, 5)
|
||
# self.output = nn.Softmax(dim=1) # Linear 自带Softmax 分类
|
||
|
||
def forward(self, x): # x: [batch_size, flow_len, packet_len] = [10, 14, 100]
|
||
embeddings_list = self.embedding(x) # [10, 14, 100, 256]
|
||
encoder_list = torch.zeros((self.batch_size, self.flow_len, 256))
|
||
for ix, embeddings in enumerate(embeddings_list): # [14, 100, 256]
|
||
# print("embeddings 1: ", embeddings.shape)
|
||
# embeddings = embeddings.permute(0, 2, 1)
|
||
# print("embeddings 2: ", embeddings.shape)
|
||
encoder1 = self.block2(embeddings) # [14, 128]
|
||
# print("encoder 1: ", encoder1.shape)
|
||
encoder2 = self.block3(embeddings) # [14, 128]
|
||
# print("encoder 2: ", encoder2.shape)
|
||
encoder = torch.cat([encoder1, encoder2], 1) # [14, 256]
|
||
# print("encoder : ", encoder.shape)
|
||
encoder_list[ix] = encoder
|
||
|
||
# rnn 网络输入:[seq_len, batch_size, hidden_size]
|
||
encoder_list = encoder_list.permute(1, 0, 2) # [10, 14, 256] -> [14, 10 ,256]
|
||
biLSTM, final_hidden_state = self.lstm_layer(encoder_list) # [14, 10, 184], [2, 10, 92]
|
||
biLSTM = biLSTM.permute(1, 0, 2) # [10, 14, 184]
|
||
# print("biLSTM: ", biLSTM.shape)
|
||
attn_output, attention = self.attention_net(biLSTM, final_hidden_state)
|
||
dense = self.dense_layer(attn_output)
|
||
# out = self.output(dense)
|
||
# out = dense[:, -1, :]
|
||
return dense
|
||
|
||
# lstm_output : [batch_size, n_step, self.byte_hidden_size * num_directions(=2)], F matrix
|
||
def attention_net(self, lstm_output, final_state):
|
||
# print("lstm_output: ", lstm_output.shape)
|
||
# print("final_state: ", final_state.shape)
|
||
# hidden : [batch_size, self.byte_hidden_size * num_directions(=2), 1(=n_layer)]
|
||
hidden = final_state.view(-1, self.gru_hidden_size * 2, 1) # Tensor维度的重构,-1表示该维度取决于其他维度
|
||
# attn_weights : [batch_size, n_step]
|
||
attn_weights = torch.bmm(lstm_output, hidden).squeeze(2) # 加权求和,第三维降维
|
||
soft_attn_weights = torch.nn.functional.softmax(attn_weights, 1)
|
||
# [batch_size, self.byte_hidden_size * num_directions(=2), n_step] * [batch_size, n_step, 1]
|
||
# = [batch_size, self.byte_hidden_size * num_directions(=2), 1]
|
||
context = torch.bmm(lstm_output.transpose(1, 2), soft_attn_weights.unsqueeze(2)).squeeze(2)
|
||
return context, soft_attn_weights # context : [batch_size, self.byte_hidden_size * num_directions(=2)]
|
||
|
||
|
||
class MyModel(nn.Module):
|
||
"""
|
||
Feature extraction module定义
|
||
"""
|
||
def __init__(self, binet, feature_dim, class_n):
|
||
super(MyModel, self).__init__()
|
||
self.binet = binet
|
||
self.feature_dim = feature_dim
|
||
self.cluster_num = class_n
|
||
""" 对比聚类 """
|
||
self.instance_projector = nn.Sequential( # 实例-单例
|
||
nn.Linear(self.binet.rep_dim, self.binet.rep_dim),
|
||
nn.ReLU(),
|
||
nn.Linear(self.binet.rep_dim, self.feature_dim),
|
||
)
|
||
self.cluster_projector = nn.Sequential( # 聚类-集群
|
||
nn.Linear(self.binet.rep_dim, self.binet.rep_dim),
|
||
nn.ReLU(),
|
||
nn.Linear(self.binet.rep_dim, self.cluster_num),
|
||
nn.Softmax(dim=1)
|
||
)
|
||
|
||
# 训练时执行
|
||
def forward(self, x_i, x_j): # x_i, x_j 来自同一数据的两种不同预处理方式得到的嵌入矩阵
|
||
h_i = self.resnet(x_i)
|
||
h_j = self.resnet(x_j)
|
||
|
||
z_i = normalize(self.instance_projector(h_i), dim=1)
|
||
z_j = normalize(self.instance_projector(h_j), dim=1)
|
||
|
||
c_i = self.cluster_projector(h_i)
|
||
c_j = self.cluster_projector(h_j)
|
||
|
||
return z_i, z_j, c_i, c_j
|
||
|
||
# 测试时执行
|
||
def forward_cluster(self, x):
|
||
h = self.resnet(x)
|
||
c = self.cluster_projector(h) # 聚类分布
|
||
c = torch.argmax(c, dim=1) # 得到每个样本的聚类标签。
|
||
return c
|
||
|
||
|
||
class MyModel1(nn.Module):
|
||
"""
|
||
模型定义
|
||
"""
|
||
def __init__(self, flow_len, packet_len, gru_units):
|
||
super(MyModel1, self).__init__()
|
||
self.packet_len = packet_len
|
||
self.flow_len = flow_len
|
||
self.batch_size = 10
|
||
self.gru_hidden_size = gru_units
|
||
|
||
self.embedding = OneHotEncodingLayer(sz=256) # 独热编码
|
||
self.block2 = ByteBlock(self.packet_len, (128, 256), (5, 5), (1, 1), (2, 2))
|
||
self.block3 = ByteBlock(self.packet_len, (192, 320), (7, 5), (1, 1), (2, 2))
|
||
|
||
self.lstm_layer = nn.GRU(256, self.gru_hidden_size, dropout=0.1, bidirectional=True)
|
||
self.dense_layer = nn.Linear(self.gru_hidden_size * 2, 5) # # 其实像特征聚类,输出聚类数
|
||
# self.output = nn.Softmax(dim=1)
|
||
|
||
def forward(self, x): # x: [batch_size, flow_len, packet_len] = [10, 14, 100]
|
||
embeddings_list = self.embedding(x) # [10, 14, 100, 256]
|
||
encoder_list = torch.zeros((self.batch_size, self.flow_len, 256))
|
||
for ix, embeddings in enumerate(embeddings_list): # [14, 100, 256]
|
||
# print("embeddings 1: ", embeddings.shape)
|
||
# embeddings = embeddings.permute(0, 2, 1)
|
||
# print("embeddings 2: ", embeddings.shape)
|
||
encoder1 = self.block2(embeddings) # [14, 128]
|
||
# print("encoder 1: ", encoder1.shape)
|
||
encoder2 = self.block3(embeddings) # [14, 128]
|
||
# print("encoder 2: ", encoder2.shape)
|
||
encoder = torch.cat([encoder1, encoder2], 1) # [14, 256]
|
||
# print("encoder : ", encoder.shape)
|
||
encoder_list[ix] = encoder
|
||
|
||
# rnn 网络输入:[seq_len, batch_size, hidden_size]
|
||
encoder_list = encoder_list.permute(1, 0, 2) # [10, 14, 256] -> [14, 10 ,256]
|
||
biLSTM, final_hidden_state = self.lstm_layer(encoder_list) # [14, 10, 184], [2, 10, 92]
|
||
biLSTM = biLSTM.permute(1, 0, 2) # [10, 14, 184]
|
||
# print("biLSTM: ", biLSTM.shape)
|
||
attn_output, attention = self.attention_net(biLSTM, final_hidden_state)
|
||
dense = self.dense_layer(attn_output)
|
||
# out = self.output(dense)
|
||
# out = dense[:, -1, :]
|
||
return dense
|
||
|
||
# lstm_output : [batch_size, n_step, self.byte_hidden_size * num_directions(=2)], F matrix
|
||
def attention_net(self, lstm_output, final_state):
|
||
# print("lstm_output: ", lstm_output.shape)
|
||
# print("final_state: ", final_state.shape)
|
||
# hidden : [batch_size, self.byte_hidden_size * num_directions(=2), 1(=n_layer)]
|
||
hidden = final_state.view(-1, self.gru_hidden_size * 2, 1) # Tensor维度的重构,-1表示该维度取决于其他维度
|
||
# attn_weights : [batch_size, n_step]
|
||
attn_weights = torch.bmm(lstm_output, hidden).squeeze(2) # 加权求和,第三维降维
|
||
soft_attn_weights = torch.nn.functional.softmax(attn_weights, 1)
|
||
# [batch_size, self.byte_hidden_size * num_directions(=2), n_step] * [batch_size, n_step, 1]
|
||
# = [batch_size, self.byte_hidden_size * num_directions(=2), 1]
|
||
context = torch.bmm(lstm_output.transpose(1, 2), soft_attn_weights.unsqueeze(2)).squeeze(2)
|
||
return context, soft_attn_weights # context : [batch_size, self.byte_hidden_size * num_directions(=2)]
|
||
|
||
if __name__ == '__main__':
|
||
#fe_model = FEMnet(14, 100, 92)
|
||
#model = MyModel(fe_model, 128, 5)
|
||
# print(model)
|
||
|
||
model = MyModel1(14, 100, 92)
|
||
data = torch.randint(255, size=(10, 14, 100)) # batch_size, flow_len, packet_len
|
||
model(data)
|
||
|
||
"""
|
||
params = list(model.parameters())
|
||
print(len(params))
|
||
print(params[0].size()) # (0): conv1's .weight
|
||
|
||
|
||
"""
|
||
|
||
|