使用python实现简单全连接神经网络

2023-11-19

最近在学习神经网络的相关知识,特在此做一个笔记。

python语言的功能很强大,可以使用很少的代码实现很多功能,因此大家如果想研究深度学习的话,一定要懂得python语言。

这篇笔记记录我的第一次使用python编写神经网络代码的过程,其中代码基本是借鉴neural networks and deep learning上的知识,这本书对神经网络学习有很大帮助,浅显易懂的深入了CNN的知识,初学者可以研究一下。

好了,多的不说,直接上代码:

这里我做的是最简单的mnist手写字的识别,首先是数据库处理。

这里我下载了42028张mnist图片,每张图片大小是28*28,需要的可以到这里下载。

一般需要把数据转化为pkl文件,便于存储和以后的使用。

import os
import cPickle
import numpy
from PIL import Image
import commondata	#自己定义的文件,里面有一些公用的变量

dirname = 'train'		#图片根目录
myfile = 'train.pkl'		#生成的文件名称

number = 0			#图片个数
for filename in os.listdir(dirname):
    filename1 = dirname + '/' + filename
    for filename2 in os.listdir(filename1):
        number += 1				</span>

pictures = numpy.empty((number,commondata.ImageWidth*commondata.ImageHeight))	#图片文件
lables = numpy.empty(number)							#标签文件

index = 0
lable = 0

for filename in os.listdir(dirname):
    filename1 = dirname + '/' + filename
    for filename2 in os.listdir(filename1):
        filename2 = filename1 + '/' + filename2
        image = Image.open(filename2)
        image = image.convert('L')					#为了简便,先统一转化为灰度图片
        image = image.resize((commondata.ImageHeight,commondata.ImageWidth))
        image_narray = numpy.asarray(image,dtype = 'float64')/256
        pictures[index] = numpy.ndarray.flatten(image_narray)
        lables[index] = lable
        index = index + 1
    lable = lable + 1

lables = lables.astype(numpy.int)
write_file=open(myfile,'wb')
cPickle.dump([pictures[:],lables[:]],write_file,-1)
write_file.close()
运行此代码,可以生成一个名字为train.pkl的文件,然后更改根目录和生成文件的名称可以得到test.pkl


生成文件后,还需要调用此文件:

import cPickle
import numpy as np
import commondata

NumClass = commondata.NumClass
ImageWidth = commondata.ImageWidth
ImageHeight = commondata.ImageHeight

def vectorized_result(j):
    e = np.zeros((NumClass,1))
    e[j] = 1.0
    return e
    
def load_data():
    f = open('data.pkl','rb')
    training_data = cPickle.load(f)
    f.close()
    
    
    f = open('test.pkl','rb')
    test_data = cPickle.load(f)
    f.close()
    
    return (training_data,test_data)

def load_data_wrapper():
    tr_d,te_d = load_data()
    training_inputs = [np.reshape(x,(ImageWidth*ImageHeight,1)) for x in tr_d[0]]
    training_results = [vectorized_result(y) for y in tr_d[1]]
    training_data = zip(training_inputs,training_results)
    test_inputs = [np.reshape(x,(ImageWidth*ImageHeight,1)) for x in te_d[0]]
    test_data = zip(test_inputs,te_d[1])
    return (training_data,test_data)
这段代码的作用是读取生成的pkl文件,并以标准化的格式返回。

其中vectorized_result的作用是将一个数值转化为向量,比如在手写数字问题中,一共有10个类,需要的向量长度为10,则1应该转化为[0,1,0,0,0,0,0,0,0,0],2应该转化为[0,0,1,0,0,0,0,0,0,0].

接下来便是最核心的代码:

import myalgorithm				#自己的算法
import numpy as np

import random

class Network(object):
    
    def __init__(self,sizes):						#初始化,sizes的形式一般为[784,50,10,10]之类的
        self.num_layers = len(sizes)
        self.sizes = sizes
        self.biases = [np.random.randn(y,1) for y in sizes[1:]]		#偏置初始化
        self.weights = [np.random.randn(y,x)				#权值初始化
                        for x,y in zip(sizes[:-1],sizes[1:])]
                            
    def feedforward(self,a):						#前向传播过程
        for b,w in zip(self.biases,self.weights):
            a = myalgorithm.sigmoid(np.dot(w,a)+b)
        return a
     
    def update_mini_batch(self,mini_batch,eta):				#根据一个minibatch训练样本调整参数
        nabla_b = [np.zeros(b.shape) for b in self.biases]
        nabla_w = [np.zeros(w.shape) for w in self.weights]
        
        for x,y in mini_batch:
            delta_nabla_b,delta_nabla_w = self.backprop(x,y)
            nabla_b = [nb + dnb for nb,dnb in zip(nabla_b,delta_nabla_b)]
            nabla_w = [nw + dnw for nw,dnw in zip(nabla_w,delta_nabla_w)]
            
        self.weights = [w - (eta/len(mini_batch))*nw
                        for w,nw in zip(self.weights,nabla_w)]
        self.biases = [b - (eta/len(mini_batch))*nb
                        for b,nb in zip(self.biases,nabla_b)]
    
    def backprop(self,x,y):						#反向传播
        nabla_b = [np.zeros(b.shape) for b in self.biases]
        nabla_w = [np.zeros(w.shape) for w in self.weights]
        
        activation = x
        activations = [x]
        zs = []
        for b,w in zip(self.biases,self.weights):
            z = np.dot(w,activation)+b
            zs.append(z)
            activation = myalgorithm.sigmoid(z)
            activations.append(activation)
            
        delta = self.cost_derivative(activations[-1],y)*myalgorithm.sigmoid_prime(zs[-1])
        nabla_b[-1] = delta
        nabla_w[-1] = np.dot(delta,activations[-2].transpose())
        for l in xrange(2,self.num_layers):
            z = zs[-l]
            sp = myalgorithm.sigmoid_prime(z)
            delta = np.dot(self.weights[-l+1].transpose(),delta) * sp
            nabla_b[-l] = delta
            nabla_w[-l] = np.dot(delta,activations[-l-1].transpose())                          
        return (nabla_b,nabla_w)

    def evaluate(self,test_data):						#测试函数
        test_results = [(np.argmax(self.feedforward(x)),y)
                        for (x,y) in test_data]
        return sum(int(x == y)for (x,y) in test_results)
        
    def cost_derivative(self,output_activations,y):				#误差函数导函数
        return (output_activations - y)
        
        
    def SGD(self,training_data,epochs,mini_batch_size,eta,test_data = None):	#SGD算法
        if test_data:
            n_test = len(test_data)
        n = len(training_data)
        for j in xrange(epochs):
            random.shuffle(training_data)
            mini_batches = [training_data[k:k+mini_batch_size] for k in xrange(0,n,mini_batch_size)]
        
            for mini_batch in mini_batches:
                self.update_mini_batch(mini_batch,eta)
            if test_data:
                print "Epoch {0}:{1}/{2}".format(j,self.evaluate(test_data),n_test)
            else:
                print "Epoch {0} complete".format(j)

代码解释见注释,

然后便可以训练:

import data
training_data,test_data = data.load_data_wrapper()

import network
net = network.Network([784,30,10])
net.SGD(training_data,30,10,1.5,test_data = test_data)

import cPickle
write_file = open('weight.pkl','wb')
cPickle.dump([net.weights[:],net.biases[:]],write_file,-1)
write_file.close()
训练完成后把权值存储起来。

如果想使用训练的模型进行分类,也很简单,如下代码:

import numpy
import commondata
from PIL import Image
import cPickle
import myalgorithm

filename = 'test1.jpg'			#需要分类的文件名

read_file = open('weight.pkl','rb')
weights,biases = cPickle.load(read_file)
read_file.close()

def outcome(weights,biases,a):
    for b,w in zip(biases,weights):
        a = myalgorithm.sigmoid(numpy.dot(w,a)+b)
    return numpy.argmax(a)

def get_predict(filename):
    image = Image.open(filename)
    image = image.convert('L')
    image = image.resize((commondata.ImageHeight,commondata.ImageWidth))
    image_narray = numpy.asarray(image,dtype = 'float64')/256
    image_vector = numpy.ndarray.flatten(image_narray)
    test = numpy.reshape(image_vector,(commondata.ImageHeight*commondata.ImageHeight,1))
    result = outcome(weights,biases,test)
    print result

 

调用get_predict函数便可以预测图片所属的类别


整个项目代码: http://download.csdn.net/detail/zsy162534/9592826



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用python实现简单全连接神经网络 的相关文章

  • DGA域名可以是色情网站域名

    恶意域名指传播蠕虫 病毒和特洛伊木马或是进行诈骗 色情内容传播等不法行为的网站域名 恶意域名指传播蠕虫 病毒和特洛伊木马或是进行诈骗 色情内容传播等不法行为的网站域名 本文面临能够的挑战 就是恶意网站经营者所使用的各种技术 近年来 FFSN
  • git lfs原理和使用

    如果我们用git管理的项目中出现了一些大文件 同时若其数量比较多 而且更新又比较频繁 那么当首次clone该项目时 就会不可避免地将这些大文件的当前版本和历史所有版本的文件都下载下来 虽然你很可能用不到这些历史文件 但是却不得不为它们所占用
  • 一般数据库服务器物理机配置,ironic部署物理机

    原标题 ironic部署物理机 ironic是openstack的帐篷项目之一 主要用来部署和管理裸机 提供统一接口 方便nova同时管理裸机和虚机 ironic的概念架构图如图1所示 本文以tecs3 0为例 介绍ironic部署裸机的流
  • border之border-style用法

    border style border style 属性用于设置元素所有边框的样式 或者单独地为各边设置边框样式 border style兼容性很好 基本所有浏览器都兼容 border style拥有一下属性值 值 描述 none 定义无边
  • 【RuoYi-Vue-Plus】问题笔记 02 - Knife4j

    文章目录 前言 问题一 文档页面空白 问题二 文档参数无法显示 问题原因 解决方案 前言 今天遇到一个很 sao 不 得 常 一 见 匹 的问题 所以必须要把这部血泪史记录一下 注 因为是开发中的项目 所以适当打码 不影响问题描述 首先描述
  • STM32入门——uKeil5 MDK 的使用(基于固件库)

    文章目录 1 Keil uVision5 MDK 是什么 2 建立一个标准库函数工程 2 1 前期准备 2 2 建立工程 2 3 建立组文件夹 2 4 添加文件 2 4 配置 魔术棒 选项卡 2 5 建立 main 函数 1 Keil uV
  • scala 学习笔记

    Scala Scala 和 java 关系 语言特点 Scala是一门以Java虚拟机 JVM 为运行环境并将面向对象和函数式编程的最佳特性结合在一起的静态类型编程语言 静态语言需要提前编译的如 Java c c 等 动态语言如 js Sc
  • 吴昊品游戏核心算法 Round 10 —— 吴昊教你下围棋(利用递归来解决吃子的问题)...

    如图所示 此即为日本动漫棋魂中的千年佐为 也就是SAI 众所周知 围棋的规则相比于中国象棋 国际象棋等等都简单许多 真是因为更简单的规则 才诞生 了更复杂的逻辑 目前的围棋AI还很不行 最NB的应该是日本人做出的后又经过众多中国的围棋爱好者
  • STM32使用HAL库,整体结构和函数原理介绍

    按照杨桃电子的说法 学习编程程序就是学习使用外设 然后需要在icode文件夹中创建对应的 c和 h文件 分三步来操作 1 学会编写板级驱动程序 2 学会在板级驱动程序中调用HAL库中的功能函数 3 学会在main 主函数中调用板级驱动程序
  • 跟李沐学AI——动手学深度学习 PyTorch版——学习笔记pycharm版本(第四天——10、11、12、13、14)2023.3.1

    前言 这是沐神的第十节课 是讲多层感知机的 需要掌握牢固 以后会经常写的 代码讲解 跳过从零开始实现 直接进入简单代码的讲解 导入包 import torch from torch import nn from d2l import tor

随机推荐

  • Git的基本使用

    Git的基本使用 一 本文主要介绍Git 实现基本的代码托管 适合初次接触Git的开发人员 高级用法请查阅后续文章 目录 Git用途 Git代码托管平台 Git工作流程 概念介绍 工作流程 Git使用步骤 版本管理 分支管理 常用的分支命名
  • 《图解物联网》--阅读笔记

    第1 章物联网的基础知识1 1 1 物联网入门 2 1 1 1 物联网 2 1 1 2 物联网的相关动向 2 1 2 物联网所实现的世界 3 1 2 1 泛在网络 社会 3 1 2 2 物 的互联网连接 4 1 2 3 机器对机器通信所实现
  • Java String类型和BigDecimal类型之间的转化及BigDecimal类型的介绍

    String和BigDecimal的相互转化 String a 50 00 字符串类型 必须是数字 否则会报错 java lang NumberFormatException 异常 BigDecimal b new BigDecimal a
  • 汇编语言有如下的汇编程序段,请完成code段中的代码,实现将string1段和string2段中的数据拷贝到string3段中,并且将string3段中的数据输出到屏幕。

    有如下的汇编程序段 请完成code段中的代码 实现将string1段和string2段中的数据拷贝到string3段中 并且将string3段中的数据输出到屏幕 题目 有如下的汇编程序段 请完成code段中的代码 实现将string1段和s
  • Bose700降噪体验

    戴了多年耳塞 还是决定买一块主动降噪的看看 第一款主动降噪耳机当然选择降噪最强的bose700 直接官方旗舰店买不废话 虽然是主动降噪 不过众所周知是主要降低频部分1KHz以下 所以呢 给小白的用话小白会说 人声 喇叭声 风扇声都是听得到的
  • 学习动态规划-子矩阵

    1 全为1的最大正方形 在一个由 0 和 1 组成的二维矩阵内 找到只包含 1 的最大正方形 并返回其面积 来源 221 最大正方形 解题思路 dp i j 表示以matrix i j 为右下角的全1的正方形的最大边长 很明显 当matri
  • C++ 之 String类详解

    String 小引 string类常用接口 常见构造 容量操作 访问操作 修改操作 string类非成员函数 模拟实现 小引 C语言中 字符串是以 0结尾的一些字符的集合 为了操作方便 C标准库中提供了一些str系列的库函数 但是这些库函数
  • MAC Android Studio 克隆新项目出现问题及解决方法

    目录 前言 重装Android Studio 卸载Android Studio 安装Android Studio 打开新项目 前言 MAC OS 10 15 1 使用Android Studio打开GIT克隆下来的新项目 报错1 Could
  • VS2022 E1696 无法打开源文件报错修改

    1 先检查安装时的配件都安装正确了没有 在工具栏位置打开 获取工具和功能 此时会跳转到我们一开始安装VS时要安装配件的界面 在该界面内 检查是否是 使用C 的桌面开发 的安装选项 如果不是的话就选中该应用并选择下载路径进行修改下载 2 如果
  • C++-std::unique_lock介绍和简单使用

    unique lock std unique lock比std lock guard更灵活 这种灵活性主要体现在以下几点 lock guard在构造时或者构造前 std adopt lock 就已经获取互斥锁 并且在作用域内保持获取锁的状态
  • Linux系统的安装(在VM虚拟机上安装CentOS 7)

    工具准备 物理计算机一台 配置要求 操作系统 win10 64位 大家基本上都是 硬盘可用容量 20G以上 内存容量 4G以上 虚拟机安装包 VMware workstation full 12 5 下载链接 点我下载 提取码 9gha C
  • 为什么程序员招聘都要5年经验起?因为他们懂Java8底层优化!

    一 前情回顾 上篇文章给大家聊了一下volatile的原理 具体参见 入坑两个月自研非外包创业公司 居然让我搞懂了volatile 这篇文章给大家聊一下java并发包下的CAS相关的原子操作 以及Java 8如何改进和优化CAS操作的性能
  • 在Qt中如何实现窗口交互

    首先介绍done函数 它的作用是 关闭当前窗口 同时返回一个状态信息 Qt助手解释 关闭对话框并将其结果代码设置为r 如果这个对话框显示了exec done 导致本地事件循环结束 exec 返回r void QDialog done int
  • checkbox样式改写

    div class checkbox font s div
  • js 微观任务、宏观任务、循环机制

    javascript是单线程语言 就是因为单线程的特性 就不得不提js中的同步和异步 同步和异步 所谓单线程 无非就是同步队列和异步队列 js代码是自上向下执行的 在主线程中立即执行的就是同步任务 比如简单的逻辑操作及函数 而异步任务不会立
  • 计算机网络--绪论

    一 计网的体系结构 1 概念和功能 2 组成和分类 3 标准化工作及相关组织 二 性能指标 1 速率 2 带宽 3 吞吐量 4 时延 5 时延带宽积 6 往返时间RTT利用率 7 利用率 三 分层结构 1 分层 四 OSI参考模型 1 OS
  • 随机数产生方法

    5 产生一定范围随机数的通用表示公式 要取得 a b 的随机整数 使用 rand b a a 要取得 a b 的随机整数 使用 rand b a 1 a 要取得 a b 的随机整数 使用 rand b a a 1 通用公式 a rand n
  • 【Vue】Vue基础自用笔记&Day02_①Vue过滤器②按键修饰符③自定义指令

    Vue基础 Day02 1 Vue过滤器 2 按键修饰符 3 自定义Vue指令 1 Vue过滤器 Vue js 允许你自定义过滤器 可被用于一些常见的文本格式化 过滤器可以用在两个地方 双花括号 插值和 v bind 表达式 后者从 2 1
  • 袁红岗的编程感悟

    我自己知道 近几年也一直在用 但就是说不出来 直到最近几天才能够表达 叫作Think in Code 也就是用代码思考 同时也把代码当成自己思想表达的方式 正如哲学家用文字设计 诠释思想 程序员 说话 用的是代码 这就是一个程序员的境 界
  • 使用python实现简单全连接神经网络

    最近在学习神经网络的相关知识 特在此做一个笔记 python语言的功能很强大 可以使用很少的代码实现很多功能 因此大家如果想研究深度学习的话 一定要懂得python语言 这篇笔记记录我的第一次使用python编写神经网络代码的过程 其中代码