python 实现简单卷积网络框架
第一步定义卷积核类:
class Filter(object):
# 滤波器类 对卷积核进行初始化
def __init__(self,width,height,depth):
# initialize the filter parameter
self.weights=np.random.uniform(-1e-4,1e-4,(depth,height,width))
self.bias=0
self.weights_grad=np.zeros(self.weights.shape)
self.bias_grad=0
def get_weights(self):
return self.weights
def get_bias(self):
return self.bias
def update_weight(self,learning_rate):
self.weights-=self.weights_grad*learning_rate
self.bias-=self.bias_grad*learning_rate
定义卷积层
def conv(input_array,kernel_array,output_array,stride,bias):
channel_number=input_array.ndim
output_width=output_array.shape[1]
output_height=output_array.shape[0]
kernel_width=kernel_array.shape[-1]
kernel_height=kernel_array.shape[-2]
for i in range(output_height):
for j in range(output_width):
# get_patch 得到i,j位置对应的图像的块
output_array[i][j]=(get_patch(input_array,i,j,kernel_width,kernel_height,stride)*kernel_array).sum()+bias
定义padding 函数:根据扩展的大小进行0填充
def padding(input_array, zero_padding):
if zero_padding == 0:
return input_array
else:
if input_array.ndim == 3:
input_width = input_array.shape[2]
input_height = input_array.shape[1]
input_depth = input_array.shape[0]
padded_array = np.zeros((input_depth, input_height + 2 * zero_padding,
input_width + 2 * zero_padding))
padded_array[:, zero_padding:zero_padding + input_height,
zero_padding:zero_padding + input_width] = input_array elif input_array.ndim == 2:
input_width = input_array.shape[1]
input_height = input_array.shape[0]
padded_array = np.zeros((input_height + 2 * zero_padding, input_width + 2 * zero_padding))
padded_array[zero_padding:zero_padding + input_width,
zero_padding:zero_padding + input_height] = input_array
return padded_array
定义卷积类:
def calculate_output_size(input_size,filter_size,zero_padding,stride):
return (input_size-filter_size+2*zero_padding)/stride+1
class ConvLayer(object):
def __init__(self,input_width,input_height,channel_number,
filter_width,filter_height,filter_number,zero_padding,stride,
activator,learning_rate):
self.input_width=input_width
self.input_height=input_height
self.channel_number=channel_number
self.filter_width=filter_width
self.filter_height=filter_height
self.filter_number=filter_number
self.zero_padding=zero_padding
self.stride=stride
# 根据(f-w+2p)/2+1
self.outpu_width=ConvLayer.calculate_output_size(self.input_width,
filter_width,zero_padding,stride)
self.output_height=ConvLayer.calculate_output_size(self.input_height,
filter_height,zero_padding,
stride)
# 得到padding 后的图像
self.output_array=np.zeros(self.filter_number,self.output_width,self.output_height)
# the output of the convolution
# 初始化filters
self.filters=[]
# initialize filters
for i in range(filter_number):
self.filters.append(Filter(filter_width,filter_height,self.channel_number))
self.activator=activator
self.learning_rate=learning_rate
# 对 灵敏度图进行扩充
def expand_sentivity_map(self,sensitivity_array):
depth=sensitivity_array.shape[0]
expanded_width=(self.input_width-self.filter_width+2*self.zero_padding+1)
expanded_height=(self.input_height-self.filter_height+2*self.zero_padding+1)
expand_array=np.zeros((depth,expanded_height,expanded_width))
for i in range(self.output_height):
for j in range(self.output_width):
i_pos=i*self.stride
j_pos=j*self.stride
expand_array[:,i_pos,j_pos]=sensitivity_array[:,i,j]
return expand_array
# 创建灵敏度矩阵
def create_delta_array(self):
return np.zeros((self.channnel_number,self.input_height,self.input_width))
# 前向传递
def forward(self,input_array):
self.input_array=input_array
# first pad image to the size needed
self.padded_input_array=padding(input_array,self.zero_padding)
for f in range(self.filter_number):
filter=self.filters[f]
conv(self.paded_input_array,filter.get_weights(),filter.get_bias())
element_wise_op(self.output_array,self.acitator.forward)
# 反向传递
def bp_sensitivity_map(self, sensitivity_array,activator):
# padding sensitivity map
expanded_array=self.expand_sentivity_map(sensitivity_array)
expanded_width=expanded_array.shape[2]
zp=(self.input_width+self.filter_width-1-expanded_width)/2
padded_array=padding(expanded_array,zp)
self.delta_array=self.create_delta_array()
for f in range(self.filter_number):
filter=self.filter[f]
filpped_weights=np.array(map(lambda i: np.rot90(i,2),filter.get_weights()))
delta_array=self.create_delta_array()
for d in range(delta_array.shape[0])
conv(padded_array[f],filpped_weights[d],delta_array[d],1,0)
self.delta_array+=delta_array
derivative_array=np.array(self.input_array)
element_wise_op(derivative_array,activator.backward)
self.delta_array*=derivative_array
# 参数的梯度是 输入乘以灵敏度矩阵
def bp_gradient(self,sensitivity_array):
expanded_array=self.expand_sensitivity_map(sensitivity_array)
for f in range(self.filter_number):
filter=self.filter[f]
for d in range(filter.weights.shape[0]):
conv(self.padded_input_array[d],expanded_array[f],filter.weights_grad[d],1,0)
filter.bias_grad=expanded_array[f].sum()
# 对参数进行update
def update(self):
for filter in self.filters:
filter.update(self.learning_rate)
python 实现简单卷积网络框架的更多相关文章
- 学习笔记TF028:实现简单卷积网络
载入MNIST数据集.创建默认Interactive Session. 初始化函数,权重制造随机噪声打破完全对称.截断正态分布噪声,标准差设0.1.ReLU,偏置加小正值(0.1),避免死亡节点(de ...
- [记录]python的简单协程框架(回调+时间循环+select)
# -*- coding: utf-8 -*- # @Time : 2018/12/15 18:55 # @File : coroutine.py #一个简单的 Coroutine 框架 import ...
- Python学习之==>Socket网络编程
一.计算机网络 多台独立的计算机通过网络通信设备连接起来的网络.实现资源共享和数据传递.在同一台电脑上可以将D盘上的一个文件传到C盘,但如果想从一台电脑传一个文件到另外一台电脑上就要通过计算机网络 二 ...
- uvloop —— 超级快的 Python 异步网络框架
简短介绍 asyncio是遵循Python标准库的一个异步 I/O框架.在这篇文章里,我将介绍 uvloop: 可以完整替代asyncio事件循环.uvloop是用Cython写的,基于 libuv. ...
- Python实现简单框架及三大框架对比
手撸web框架 简单的请求响应实现 要实现最简单的web框架,首先要对网络熟悉,首先HTTP协议是应用层的协议,只要我们给数据加上HTTP格式的响应报头,我们的数据就能基于socket进行实现了 im ...
- python网络框架Twisted
什么是Twisted Twisted是一个用python语言写的事件驱动网络框架,它支持很多种协议,包括UDP,TCP,TLS和其他应用层协议,比如HTTP,SMTP,NNTM,IRC,XMPP/Ja ...
- 用Python写一个简单的Web框架
一.概述 二.从demo_app开始 三.WSGI中的application 四.区分URL 五.重构 1.正则匹配URL 2.DRY 3.抽象出框架 六.参考 一.概述 在Python中,WSGI( ...
- iOS开发网络篇—简单介绍ASI框架的使用
iOS开发网络篇—简单介绍ASI框架的使用 说明:本文主要介绍网络编程中常用框架ASI的简单使用. 一.ASI简单介绍 ASI:全称是ASIHTTPRequest,外号“HTTP终结者”,功能十分强大 ...
- Android中android-async-http开源网络框架的简单使用
android-async-http开源网络框架是专门针对Android在Apache的基础上构建的异步且基于回调的http client.所有的请求全在UI线程之外发生,而callback发生在创建 ...
随机推荐
- 安装和使用 memcached
memcached 和 Grails,第 1 部分:安装和使用 memcached 学习 memcached 命令并评估缓存性能 本文是系列文章的第 1 部分,主要介绍 memcached 和 Gra ...
- 2019年桌面Linux需要做好的7件事
2019年桌面Linux需要做好的7件事 新的一年已经到来,这意味着又一年过去了,Linux还是没有发现自己主宰了桌面.Linux在许多方面做得非常好,在接下来的几周,我们将研究一些最适合您各种需求的 ...
- leetcode 5 查找最长的回文子串
给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 1: 输入: "babad" 输出: "bab" 注意: &qu ...
- keras 中模型的保存
参考:https://www.cnblogs.com/weiyinfu/p/9788179.html#0 1.model.summary() 这个函数会打印模型结构,但是仅仅是打印到控制台,不能保存 ...
- 洛谷 P1049 装箱问题
\[传送门在这呢!!\] 题目描述 有一个箱子容量为\(V\)(正整数,\(0 \le V \le 20000\)),同时有\(n\)个物品(\(0<n \le 30\),每个物品有一个体积(正 ...
- C++ 标准库之 iomanip 、操作符 ios::fixed 以及 setprecision 使用的惨痛教训经验总结
本菜鸡自从退役之后就再也没怎么敲过 C++ 代码,在 C++ 语言下,求解关于浮点数类型的问题时,之前有碰到类似的情况,但是似乎都没有卡这块的数据,基本上用一个 setprecision 函数保留几位 ...
- Binary Search(Java)(非递归)
public static int rank(int[] array, int k) { int front = 0, rear = array.length - 1; while(front < ...
- 【转】Spark实现行列转换pivot和unpivot
背景 做过数据清洗ETL工作的都知道,行列转换是一个常见的数据整理需求.在不同的编程语言中有不同的实现方法,比如SQL中使用case+group,或者Power BI的M语言中用拖放组件实现.今天正好 ...
- Django组件之Form表单
一.Django中的Form表单介绍 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来. 与此同时我们在好多场景下都需要对用户的输入 ...
- property与x.setter与x.deleter
#测试property,x.setter,x.deleter class Test1: def __init__(self): self.__private = "alex" @p ...