# -*- coding: utf-8 -*-
 """
 Created on Sun Mar  4 09:21:41 2018

 @author: markli
 """
 import numpy as np;

 def ReLU(x):
     return max(0,x);

 def logistic(x):
     return 1/(1 + np.exp(-x));

 def logistic_derivative(x):
     return logistic(x)*(1-logistic(x));

 class ConvolutionLayer:
     """
     卷积神经网络中的卷积层
     """
     def __init__(self,shape,padding,filters,stride):
         """
         shape 卷积层形状,元组 (行,列,通道数)
         padding 填充零个数的大小
         filters 过滤器的形状,元组 (行,列,通道数,个数)
         stride 步长
         """
         self.shape = shape;
         self.padding = padding;
         self.stride = stride;
         self.fileters = filters[:3];
         self.fileternum = filters[3];
         self.weights = [];
         for i in range(filters[3]):
             self.weights.append(np.random.randn(shape[2],filters[0],filters[1]));
         self.baises = list(np.random.randn(filters[3]));

         self.convlutionsize = (int((shape[0] + 2*padding - filters[0])/stride + 1),int((shape[1] + 2*padding - filters[1])/stride + 1));
         self.conv = np.ones((filters[3],self.convlutionsize[0],self.convlutionsize[1]));

     def Convolute(self,Data):
         """
         Data 三维数组,若只有两维则通道数设为1.
         """
         if(self.padding != 0):
             for c in range(self.shape[2]):
                 ones = np.zeros((self.shape[0]+2*self.padding,self.shape[1]+2*self.padding));
                 ones[self.padding:self.padding+self.shape[0],self.padding:self.padding+self.shape[1]] = Data[c];
                 Data[c] = ones;
         c,m,n = Data.shape;

         #遍历每一个过滤器
         for f in range(self.fileternum):
             t_conv = self.conv[f]; #取出第f个过滤器卷积后的临时容器
             w = self.weights[f]; #取出第f个过滤器的权值集合
             b = self.baises[f]; #取出第f个过滤器的偏倚
             #卷积运算,所有通道一起遍历
             row = 0;
             for i in range(self.convlutionsize[0]):
                 col = 0;
                 for j in range(self.convlutionsize[1]):
                     data = Data[:,row:row+self.fileters[0],col:col+self.fileters[1]]; #取出卷积运算的数据立方体
                     s = 0; #存放卷积立方体的乘积的和
                     #对取出的临时数据的每个通道进行卷积运算
                     for t_c in range(c):
                         t_w = w[t_c];
                         t_data = data[t_c];
                         temp = sum(np.multiply(t_w,t_data));
                         s = temp + s;
                     t_conv[i,j] = ReLU(s+b);
                     #向右移动过滤器
                     col = col + self.stride;
                 #向下移动过滤器
                 row = row + self.stride;
             #更新卷积结果容器
             self.conv[f] = t_conv;

 class PoolLayer:
     """池化层"""
     def __init__(self,shape,poolsize,stride,classic="max"):
         """
         shape 池化目标的形状, 元组(行,列,通道数)
         poolsize 池化矩阵的形状,元组 (行,列)
         stride 步长 一般情况下池化的步长等于池化大小
         classic 池化方式 max,average
         """
         self.shape = shape;
         self.stride = stride;
         self.poolsize = poolsize;
         self.classic = classic;
         #生成池化结果矩阵形状
         self.pool = np.ones((shape[2],(shape[0]-poolsize[0])/stride + 1,(shape[1]-poolsize[1])/stride + 1));
         #生成过度池化矩阵形状
         self.c_poolsize = ((shape[0]-poolsize[0])/stride + 1,(shape[1]-poolsize[1])/stride + 1);

     def Pool(self,Data):
         """
         Data 三维数组,若只有两维则通道数设为1.
         """
         c,m,n = Data.shape;

         #在每个通道上进行池化操作
         for k in range(c):
             p_temp = Data[k];
             row = 0;
             for i in range(self.c_poolsize[0]):
                 col = 0;
                 for j in range(self.c_poolsize[1]):
                     temp = p_temp[row:row+self.poolsize[0],col:col+self.poolsize[1]];
                     if(self.classic == "average"):
                         self.pool[k][i][j] = np.sum(temp) / (self.poolsize[0] * self.poolsize[1]);
                     if(self.classic == "max"):
                         self.pool[k][i][j] = np.max(temp);
                     else:
                         print("the classic does not exist");

                     col = col + self.stride;

                 row = row + self.stride;

 class FullConnectLayer:
     """全连接层"""
     def __init__(self,n_in,n_out,action_fun=logistic,action_fun_der=logistic_derivative,flag):
         """
         n_in 输入层的单元数
         n_out 输出单元个数 及紧邻下一层的单元数
         action_fun 激活函数
         action_fun_der 激活函数的导函数
         flag 初始化权值和偏倚的标记 normal,larger,smaller
         """
         self.action_fun = action_fun;
         self.action_fun_der = action_fun_der;
         self.n_in = n_in;
         self.n_out = n_out;
         init_weight_biase(flag);

     def init_weight_biase(self,init_flag):
         if(init_flag == "noraml"):
             self.weight = np.random.randn(self.n_out,self.n_in);#weight 取值服从N(0,1) 分布
             self.biase = np.random.randn(self.n_out,1);
         elif(init_flag == "larger"):
             self.weight = 2*np.random.randn(self.n_out,self.n_in)-1; #weight 取值范围(-1,1)
             self.biases = 2*np.random.randn(self.n_out,1)-1 ; #b 取值范围(-1,1)
         elif(init_flag == "smaller"):
             self.weight = np.random.randn(self.n_out,self.n_in)/np.sqrt(self.n_out) ; #weight 取值服从N(0,1/x) 分布
             self.biase = np.random.randn(self.n_out,1);

     def Forward(self,inpt):
         """全连接层的前馈传播"""
         self.inpt = np.dot(self.weight,inpt) + self.biase;
         self.outpt = self.action_fun(self.inpt);

 """Softmax Layer"""

后向传播的实现还是没有头绪,三层之间如何衔接不知道该怎么设计。本人能力水平有限,欢迎交流。本人微信号 markli52024

Python3 卷积神经网络卷积层,池化层,全连接层前馈实现的更多相关文章

  1. tensorflow 1.0 学习:池化层(pooling)和全连接层(dense)

    池化层定义在 tensorflow/python/layers/pooling.py. 有最大值池化和均值池化. 1.tf.layers.max_pooling2d max_pooling2d( in ...

  2. 深度学习原理与框架-Tensorflow卷积神经网络-卷积神经网络mnist分类 1.tf.nn.conv2d(卷积操作) 2.tf.nn.max_pool(最大池化操作) 3.tf.nn.dropout(执行dropout操作) 4.tf.nn.softmax_cross_entropy_with_logits(交叉熵损失) 5.tf.truncated_normal(两个标准差内的正态分布)

    1. tf.nn.conv2d(x, w, strides=[1, 1, 1, 1], padding='SAME')  # 对数据进行卷积操作 参数说明:x表示输入数据,w表示卷积核, stride ...

  3. CNN学习笔记:全连接层

    CNN学习笔记:全连接层 全连接层 全连接层在整个网络卷积神经网络中起到“分类器”的作用.如果说卷积层.池化层和激活函数等操作是将原始数据映射到隐层特征空间的话,全连接层则起到将学到的特征表示映射到样 ...

  4. mnist全连接层网络权值可视化

    一.数据准备 网络结构:lenet_lr.prototxt 训练好的模型:lenet_lr_iter_10000.caffemodel 下载地址:链接:https://pan.baidu.com/s/ ...

  5. 【深度学习篇】--神经网络中的池化层和CNN架构模型

    一.前述 本文讲述池化层和经典神经网络中的架构模型. 二.池化Pooling 1.目标 降采样subsample,shrink(浓缩),减少计算负荷,减少内存使用,参数数量减少(也可防止过拟合)减少输 ...

  6. 神经网络中的池化层(pooling)

    在卷积神经网络中,我们经常会碰到池化操作,而池化层往往在卷积层后面,通过池化来降低卷积层输出的特征向量,同时改善结果(不易出现过拟合).为什么可以通过降低维度呢? 因为图像具有一种“静态性”的属性,这 ...

  7. caffe中全卷积层和全连接层训练参数如何确定

    今天来仔细讲一下卷基层和全连接层训练参数个数如何确定的问题.我们以Mnist为例,首先贴出网络配置文件: name: "LeNet" layer { name: "mni ...

  8. 全连接层(FC)与全局平均池化层(GAP)

    在卷积神经网络的最后,往往会出现一两层全连接层,全连接一般会把卷积输出的二维特征图转化成一维的一个向量,全连接层的每一个节点都与上一层每个节点连接,是把前一层的输出特征都综合起来,所以该层的权值参数是 ...

  9. resnet18全连接层改成卷积层

    想要尝试一下将resnet18最后一层的全连接层改成卷积层看会不会对网络效果和网络大小有什么影响 1.首先先对train.py中的更改是: train.py代码可见:pytorch实现性别检测 # m ...

随机推荐

  1. [翻译]Java日志终极指南

    本文由 ImportNew - Wing 翻译自 loggly.欢迎加入翻译小组.转载请见文末要求. Java日志基础 Java使用了一种自定义的.可扩展的方法来输出日志.虽然Java通过java.u ...

  2. 字符串截取函数substr()

    substr(参数1,参数2[,参数3]); 该系统函数返回被截后的子字符串,它接受2个必选参数,参数1为要截取的字符串,参数2为截取的开始位置,参数3可选,表示截取长度. 例子:substr(&qu ...

  3. iOS下的实际网络连接状态检测(转)

    序言 网络连接状态检测对于我们的iOS app开发来说是一个非常通用的需求.为了更好的用户体验,我们会在无网络时展现本地或者缓存的内容,并对用户进行合适的提示.对绝大部分iOS开发者来说,从苹果示例代 ...

  4. activity点击时各种方法的区别

    用到不同方法时候某些系统有不太一样的情况: public class MainActivity extends Activity { private static String TAG = " ...

  5. IOC容器在框架中的应用

    IOC容器在框架中的应用 前言 在上一篇我大致的介绍了这个系列所涉及到的知识点,在本篇我打算把IOC这一块单独提取出来讲,因为IOC容器在解除框架层与层之间的耦合有着不可磨灭的作用.当然在本系列前面的 ...

  6. ado vb6

    http://www.cnblogs.com/ywb-lv/articles/2343444.html http://stackoverflow.com/questions/3334102/use-t ...

  7. OpenLayer3调用天地图示例

    最近,工作中有需要用Openlayer3脚本库调用天地图的wmts服务接口,由于这两个都是刚开始接触,所以是摸着石头过河,遇到了地图显示不了的问题,虽然官网http://www.zjditu.cn/r ...

  8. bzoj 4006: [JLOI2015]管道连接

    Description 小铭铭最近进入了某情报部门,该部门正在被如何建立安全的通道连接困扰. 该部门有 n 个情报站,用 1 到 n 的整数编号.给出 m 对情报站 ui;vi 和费用 wi,表示情 ...

  9. 详解MariaDB数据库的触发器

    1.什么是触发器 触发器是一种特殊的存储过程,它在插入,删除或修改特定表中的数据时触发执行 它比数据库本身标准的功能有更精细和更复杂的数据控制能力 2.触发器的作用: 2.1 安全性 可以基于数据库的 ...

  10. static:get()什么意思

    在类里面static关键词相当于self关键词