文章目录

  • 1.问题描述
  • 2.Dense定义在`build`的时候提前获得卷积、池化的输出尺寸
    • 关键代码:build
    • 关键代码:call
    • 全部代码

1.问题描述

自定义Keras类的时候,在build方法里定义好卷积、池化、全连接。因为全连接要给输入维度,它牵扯到每次卷积-池化后的维度,所以想在build的时候获取定义卷积和池化后的输出尺寸。

全连接可以定义在call里,不用提前获得尺寸,但是要通过自定义循环的方式训练。
自定义循环训练看:https://blog.csdn.net/qq_42363032/article/details/122703588?spm=1001.2014.3001.5501

因为我要做FGCNN,所以此处演示数据为结构化数据

2.Dense定义在build的时候提前获得卷积、池化的输出尺寸

关键代码:build

def build(self, input_shape):embedding_size = int(input_shape[-1])pooling_shape = input_shape.as_list() + [1, ]  # [None, n, k, 1]self.conv_layers = []self.pooling_layers = []self.dense_layers = []for i in range(len(self.filters)):conv_output_shape = self._conv_output_shape(pooling_shape, (self.kernel_with[i], 1))pooling_shape = self._pooling_output_shape(conv_output_shape, (self.pooling_width[i], 1))self.conv_layers.append(layers.Conv2D(filters=self.filters[i], kernel_size=(self.kernel_with[i], 1), strides=(1, 1), padding='same', activation='tanh'))self.pooling_layers.append(layers.MaxPooling2D(pool_size=(self.pooling_width[i], 1)))self.dense_layers.append(layers.Dense(pooling_shape[1] * embedding_size * self.dnn_maps[i], activation='tanh', use_bias=True))self.flatten_layer = layers.Flatten()
def _conv_output_shape(self, input_shape, kernel_size):space = input_shape[1:-1]  # [n, k]new_space = []for i in range(len(space)):new_dim = utils.conv_output_length(space[i], kernel_size[i], padding='same', stride=1, dilation=1)new_space.append(new_dim)return ([input_shape[0]] + new_space + [self.filters])def _pooling_output_shape(self, input_shape, pool_size):rows = input_shape[1]cols = input_shape[2]rows = utils.conv_output_length(rows, pool_size[0], 'valid', pool_size[0])cols = utils.conv_output_length(cols, pool_size[1], 'valid', pool_size[1])return [input_shape[0], rows, cols, input_shape[3]]

关键代码:call

def call(self, inputs, **kwargs):k = inputs.shape[-1]new_feature_list = []x = tf.expand_dims(inputs, axis=-1)  # [None, n, k, 1] 最后一维为通道for i in range(len(self.filters)):x = self.conv_layers[i](x)     # [None, n, k, filters[i]]x = self.pooling_layers[i](x)  # [None, n/poolwidth[i], k, filters[i]]out = self.flatten_layer(x)    # [None, n/poolwidth[i] * k * filters[i]]out = self.dense_layers[i](out)out = tf.reshape(out, shape=(-1, out.shape[1] // k, k))new_feature_list.append(out)output = tf.concat(new_feature_list, axis=1)return output

全部代码

# coding:utf-8
import time
import numpy as np, pandas as pd
import tensorflow as tf
from tensorflow.python.layers import utils
from tensorflow.keras import layers
from tensorflow.keras import Model
from tensorflow.keras import optimizers
from tensorflow.keras import metrics
from tensorflow.keras import regularizers
from keras import backend as K
from sklearn.model_selection import train_test_split
from sklearn.metrics import precision_score, recall_score, accuracy_score, f1_score, roc_auc_score
from sklearn.utils import shufflefrom tools import *
from settings import *class DNN_layers(layers.Layer):def __init__(self, hidden_units, activation, droup_out):super(DNN_layers, self).__init__()self.DNN = tf.keras.Sequential()for hidden in hidden_units:# self.DNN.add(layers.Dense(hidden, kernel_regularizer=regularizers.l2()))self.DNN.add(layers.Dense(hidden))self.DNN.add(layers.BatchNormalization())self.DNN.add(layers.Activation(activation))self.DNN.add(layers.Dropout(droup_out))def call(self, inputs, **kwargs):return self.DNN(inputs)class FGCNN_layers(layers.Layer):def __init__(self, filters=[14, 16], kernel_with=[7, 7], dnn_maps=[3, 3], pooling_width=[2, 2]):super(FGCNN_layers, self).__init__()self.filters = filtersself.kernel_with = kernel_withself.dnn_maps = dnn_mapsself.pooling_width = pooling_widthdef build(self, input_shape):embedding_size = int(input_shape[-1])pooling_shape = input_shape.as_list() + [1, ]  # [None, n, k, 1]self.conv_layers = []self.pooling_layers = []self.dense_layers = []for i in range(len(self.filters)):conv_output_shape = self._conv_output_shape(pooling_shape, (self.kernel_with[i], 1))pooling_shape = self._pooling_output_shape(conv_output_shape, (self.pooling_width[i], 1))self.conv_layers.append(layers.Conv2D(filters=self.filters[i], kernel_size=(self.kernel_with[i], 1), strides=(1, 1), padding='same', activation='tanh'))self.pooling_layers.append(layers.MaxPooling2D(pool_size=(self.pooling_width[i], 1)))self.dense_layers.append(layers.Dense(pooling_shape[1] * embedding_size * self.dnn_maps[i], activation='tanh', use_bias=True))self.flatten_layer = layers.Flatten()def call(self, inputs, **kwargs):k = inputs.shape[-1]new_feature_list = []x = tf.expand_dims(inputs, axis=-1)  # [None, n, k, 1] 最后一维为通道for i in range(len(self.filters)):x = self.conv_layers[i](x)     # [None, n, k, filters[i]]x = self.pooling_layers[i](x)  # [None, n/poolwidth[i], k, filters[i]]out = self.flatten_layer(x)    # [None, n/poolwidth[i] * k * filters[i]]out = self.dense_layers[i](out)out = tf.reshape(out, shape=(-1, out.shape[1] // k, k))new_feature_list.append(out)output = tf.concat(new_feature_list, axis=1)return outputdef _conv_output_shape(self, input_shape, kernel_size):space = input_shape[1:-1]  # [n, k]new_space = []for i in range(len(space)):new_dim = utils.conv_output_length(space[i], kernel_size[i], padding='same', stride=1, dilation=1)new_space.append(new_dim)return ([input_shape[0]] + new_space + [self.filters])def _pooling_output_shape(self, input_shape, pool_size):rows = input_shape[1]cols = input_shape[2]rows = utils.conv_output_length(rows, pool_size[0], 'valid', pool_size[0])cols = utils.conv_output_length(cols, pool_size[1], 'valid', pool_size[1])return [input_shape[0], rows, cols, input_shape[3]]class FGCNN(Model):def __init__(self, dense_feature_columns, sparse_feature_columns, hidden_units, activation, dropout,filters=[14, 16], kernel_with=[7, 7], dnn_maps=[3, 3], pooling_width=[2, 2]):super(FGCNN, self).__init__()self.sparse_feature_columns = sparse_feature_columnsself.dense_feature_columns = dense_feature_columnsself.emb_layers = [layers.Embedding(feat['vocabulary_size'], feat['embed_dim']) for i, feat in enumerate(self.sparse_feature_columns)]self.fgcnn_layers = FGCNN_layers(filters=filters, kernel_with=kernel_with, dnn_maps=dnn_maps, pooling_width=pooling_width)self.dnn_layers = DNN_layers(hidden_units, activation, dropout)self.out_layers = layers.Dense(1)def call(self, inputs, training=None, mask=None):dense_inputs, sparse_inputs = inputs[:, :13], inputs[:, 13:]sparse_embed = [layer(sparse_inputs[:, i]) for i, layer in enumerate(self.emb_layers)]  # 26 * [None, k]# 卷积要求输入为4维sparse_embed = tf.transpose(tf.convert_to_tensor(sparse_embed), [1, 0, 2])  # [None, 26, k]fgcnn_out = self.fgcnn_layers(sparse_embed)  # [None, new_n, k]sparse_embed = tf.concat([sparse_embed, fgcnn_out], axis=1)sparse_embed = tf.reshape(sparse_embed, shape=[-1, sparse_embed.shape[1] * sparse_embed.shape[2]])input = tf.concat([dense_inputs, sparse_embed], axis=1)out = self.dnn_layers(input)return tf.nn.sigmoid(self.out_layers(out))if __name__ == '__main__':data = pd.read_csv(criteo_sampled_data_path)data = shuffle(data, random_state=42)data_X = data.iloc[:, 1:]data_y = data['label'].values# I1-I13:总共 13 列数值型特征# C1-C26:共有 26 列类别型特征dense_features = ['I' + str(i) for i in range(1, 14)]sparse_features = ['C' + str(i) for i in range(1, 27)]dense_feature_columns = [denseFeature(feat) for feat in dense_features]sparse_feature_columns = [sparseFeature(feat, data_X[feat].nunique(), 8) for feat in sparse_features]feature_columns = [dense_feature_columns + sparse_feature_columns]tmp_X, test_X, tmp_y, test_y = train_test_split(data_X, data_y, test_size=0.05, random_state=42, stratify=data_y)train_X, val_X, train_y, val_y = train_test_split(tmp_X, tmp_y, test_size=0.05, random_state=42, stratify=tmp_y)print(len(train_y))print(len(val_y))print(len(test_y))model = FGCNN(dense_feature_columns=dense_feature_columns, sparse_feature_columns=sparse_feature_columns,hidden_units=(64, 128, 256), activation='relu', dropout=0.0)callbacks = [tf.keras.callbacks.EarlyStopping(monitor='val_loss', min_delta=1e-8, patience=3, verbose=1)]# adam = optimizers.Adam(lr=config['train']['adam_lr'], beta_1=0.95, beta_2=0.96, decay=config['train']['adam_lr'] / config['train']['epochs'])adam = optimizers.Adam(lr=1e-4, beta_1=0.95, beta_2=0.96)model.compile(optimizer=adam,loss='binary_crossentropy',metrics=[metrics.AUC(), metrics.Precision(), metrics.Recall(), 'accuracy'],# metrics=[metrics.AUC(), 'accuracy'],# run_eagerly=True,)model.fit(train_X.values, train_y,validation_data=(val_X.values, val_y),batch_size=2000,epochs=10,verbose=2,shuffle=True,# callbacks=callbacks,)scores = model.evaluate(test_X.values, test_y, verbose=2)print(' %s: %.4f' % (model.metrics_names[0], scores[0]))print(' %s: %.4f' % (model.metrics_names[1], scores[1]))print(' %s: %.4f' % (model.metrics_names[2], scores[2]))print(' %s: %.4f' % (model.metrics_names[3], scores[3]))print(' %s: %.4f' % ('F1', (2 * scores[2] * scores[3]) / (scores[2] + scores[3])))print(' %s: %.4f' % (model.metrics_names[4], scores[4]))# y_pre_sc = model.predict(test_X.values, batch_size=256)

conv_output_length 在全连接之前获取定义的卷积和池化的输出维度相关推荐

  1. 【数据挖掘】卷积神经网络 ( 池化 | 丢弃 | 批量规范化 | 卷积神经网络完整流程示例 | 卷积 | 池化 | 全连接 | 输出 | 卷积神经网络总结 )

    文章目录 I . 池化 II . 丢弃操作 III . 批量规范化 IV . 卷积神经网络 完整流程示例 ( 1 ) : 原始输入图 V . 卷积神经网络 完整流程示例 ( 2 ) : 卷积层 C1C ...

  2. 使用CNN实现图像分类——理解卷积神经网络(卷积、池化、全连接)

    1. 卷积神经网络(CNN)简介 19世纪60年代,科学家通过对猫的视觉皮层细胞研究发现,每一个视觉神经元只会处理一小块区域的视觉图像,即感受野(Receptive Field).卷积神经网络的概念即 ...

  3. 卷积层和全连接层的区别_CNN卷积层、全连接层的参数量、计算量

    我们以VGG-16为例,来探讨一下如何计算卷积层.全连接层的参数量.计算量.为了简单.直观地理解,以下讨论中我们都会忽略偏置项,实践中必须考虑偏置项. [卷积层的参数量] 什么是卷积层的参数? 卷积层 ...

  4. 深度学习笔记(一):卷积层+池化层+激活函数+全连接层

    写在前面:大家好!我是[AI 菌],一枚爱弹吉他的程序员.我热爱AI.热爱分享.热爱开源! 这博客是我对学习的一点总结与记录.如果您也对 深度学习.机器视觉.算法.Python.C++ 感兴趣,可以关 ...

  5. 卷积层和全连接层的区别_卷积神经网络中全连接层作用理解总结

    前言 一般来说,卷积神经网络会有三种类型的隐藏层--卷积层.池化层.全连接层.卷积层和池化层比较好理解,主要很多教程也会解释. •  卷积层(Convolutional layer)主要是用一个采样器 ...

  6. 2 RepMLP:卷积重参数化为全连接层进行图像识别 (Arxiv)

    论文地址: RepMLP: Re-parameterizing Convolutions into Fully-connected Layers for Image Recognition​arxiv ...

  7. 卷积神经网络与全连接神经网络

    1.定义 在全连接神经网络中,每两层之间的节点都有边相连. 卷积神经网络也是通过一层一层的节点组织起来的,对于卷积神经网络,相邻两层之间只有部分节点相连.在卷积神经网络的前几层中,每一层的节点都被组织 ...

  8. 【卷积神经网络】卷积层,池化层,全连接层

    转于:<入门PyTorch> 卷积层是卷积神经网络的核心, 大多数计算都是在卷积层中进行的. 1 卷积层 1.1 概述 首先介绍卷积神经网络的参数. 这些参数是由一些可学习的滤波器集合构成 ...

  9. “重参数宇宙”再添新成员:RepMLP,清华大学旷视科技提出将重参数卷积嵌入到全连接层

    编辑:Happy 首发:AIWalker paper: https://arxiv.org/abs/2105.01883 code: https://github.com/DingXiaoH/RepM ...

最新文章

  1. 模型可解释性-树结构可视化
  2. python中的Lock与RLock
  3. Strut2中单元测试实例
  4. 利用STM32制作红外测温仪之硬件设计
  5. 【译】响应式CSS动画
  6. 【服务器】在 iPad 上运行 VSCode(宝塔+code server)
  7. idea设置提示重复代码下去掉波浪线
  8. ANSYS命令流——圆柱体网格划分
  9. 混沌时间序列的 rbf 预测
  10. SpringCloud-config分布式配置中心
  11. Http中header与body的区别
  12. 【Python】 Python编程基础练习100题学习记录第七期(61~70)
  13. android编辑框禁用emoji表情和颜文字
  14. Google Maps Api Geocoding 传递参数和返回参数的解析(Json)
  15. python count函数用法示例_python count函数用法详解
  16. 关于我在一家网络科技有限公司的工作经历
  17. iOS 字体的加粗和其他样式的效果
  18. XSS攻击绕过过滤方法大全(转)
  19. 网工扫盲篇:MPLS TE是什么?
  20. 计算机管理3d设置在哪,nvidia控制面板3D怎么设置玩游戏最好?-电脑自学网

热门文章

  1. Github 每日精选:可在Java 中绑定 skia 的 2D 图形库Skija;自动对对联系统seq2seq-couplet
  2. 在手机上怎样剪辑视频?一键把视频分享出去
  3. 浏览器好用的插件集合
  4. 何必对吴莹莹如此苛刻 吴莹莹也是受害者
  5. 亚马逊饱受争议的AI识图工具Rekognition,正被用于提取医学图像中的患者隐私...
  6. Django 数据库查询优化,choices参数(数据库字段设计常见),MVC和MTV模型,多对多三种创建方式...
  7. java编程如何算圆的面具,Java实现人物拼图游戏│附代码
  8. android自定义table,Android 自定义表格控件
  9. 使用Kotlin Native技术开发iOS应用
  10. Win10 开机进桌面黑屏只有鼠标可以移动,任务管理器运行explorer没反应