WinSocket模型的探讨——完成端口模型

windows socket封装(完成端口,select) 基于第一个版本比较粗糙,目前对windows下实用的模式进行封装,以达到简单易用,并且完善了第一个版本中的处理不当问题,更为完善。下载分值也更低 立即下载

众所皆知,完成端口是在WINDOWS平台下效率最高,扩展性最好的IO模型,特别针对于WINSOCK的海量连接时,更能显示出其威力。其实建立一个完成端口的服务器也很简单,只要注意几个函数,了解一下关键的步骤也就行了。

这是篇完成端口入门级的文章,分为以下几步来说明完成端口: 

  1. 函数
  2. 常见问题以及解答
  3. 步骤
  4. 例程

1、函数:

我们在完成端口模型下会使用到的最重要的两个函数是:
CreateIoCompletionPort、GetQueuedCompletionStatus

CreateIoCompletionPort  的作用是创建一个完成端口和把一个IO句柄和完成端口关联起来:

// 创建完成端口
HANDLE CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);

// 把一个IO句柄和完成端口关联起来,这里的句柄是一个socket 句柄
CreateIoCompletionPort((HANDLE)sClient, CompletionPort, (DWORD)PerHandleData, 0);

其中第一个参数是句柄,可以是文件句柄、SOCKET句柄。
第二个就是我们上面创建出来的完成端口,这里就把两个东西关联在一起了。
第三个参数很关键,叫做PerHandleData,就是对应于每个句柄的数据块。我们可以使用这个参数在后面取到与这个SOCKET对应的数据。
最后一个参数给0,意思就是根据CPU的个数,允许尽可能多的线程并发执行。

GetQueuedCompletionStatus 的作用就是取得完成端口的结果:

// 从完成端口中取得结果
GetQueuedCompletionStatus(CompletionPort, &BytesTransferred, (LPDWORD)&PerHandleData, (LPOVERLAPPED*)&PerIoData, INFINITE)

第一个参数是完成端口
第二个参数是表明这次的操作传递了多少个字节的数据
第三个参数是OUT类型的参数,就是前面CreateIoCompletionPort传进去的单句柄数据,这里就是前面的SOCKET句柄以及与之相对应的数据,这里操作系统给我们返回,让我们不用自己去做列表查询等操作了。
第四个参数就是进行IO操作的结果,是我们在投递 WSARecv / WSASend 等操作时传递进去的,这里操作系统做好准备后,给我们返回了。非常省事!!

个人感觉完成端口就是操作系统为我们包装了很多重叠IO的不爽的地方,让我们可以更方便的去使用,下篇我将会尝试去讲述完成端口的原理。

2、常见问题和解答

a、什么是单句柄数据(PerHandle)和单IO数据(PerIO)

单句柄数据就是和句柄对应的数据,像socket句柄,文件句柄这种东西。

单IO数据,就是对应于每次的IO操作的数据。例如每次的WSARecv/WSASend等等

其实我觉得PER是每次的意思,翻译成每个句柄数据和每次IO数据还比较清晰一点。

在完成端口中,单句柄数据直接通过GetQueuedCompletionStatus 返回,省去了我们自己做容器去管理。单IO数据也容许我们自己扩展OVERLAPPED结构,所以,在这里所有与应用逻辑有关的东西都可以在此扩展。

b、如何判断客户端的断开

我们要处理几种情况

1) 如果客户端调用了closesocket,我们就可以这样判断他的断开:

if(0 == GetQueuedCompletionStatus(CompletionPort, &BytesTransferred, 。。。)
{
}
if(BytesTransferred == 0)
{
    // 客户端断开,释放资源
}

2) 如果是客户端直接退出,那就会出现64错误,指定的网络名不可再用。这种情况我们也要处理的:

if(0 == GetQueuedCompletionStatus(。。。))
{
   if( (GetLastError() == WAIT_TIMEOUT) || (GetLastError() == ERROR_NETNAME_DELETED) )
   {
        // 客户端断开,释放资源
   }
}

3、步骤

编写完成端口服务程序,无非就是以下几个步骤:

  1、创建一个完成端口
  2、根据CPU个数创建工作者线程,把完成端口传进去线程里
  3、创建侦听SOCKET,把SOCKET和完成端口关联起来
  4、创建PerIOData,向连接进来的SOCKET投递WSARecv操作

  5、线程里所做的事情:
 a、GetQueuedCompletionStatus,在退出的时候就可以使用PostQueudCompletionStatus使线程退出
 b、取得数据并处理

4、例程

下面是服务端的例程,可以使用《WinSocket模型的探讨——Overlapped模型(一)》中的客户端程序来测试次服务端。稍微研究一下,也就会对完成端口模型有个大概的了解了。

/*

   完成端口服务器

   接收到客户端的信息,直接显示出来

*/

#include "winerror.h"
#include "Winsock2.h"
#pragma comment(lib, "ws2_32")

#include "windows.h"


#include <iostream>
using namespace std;


/// 宏定义
#define PORT 5050
#define DATA_BUFSIZE 8192

#define OutErr(a) cout << (a) << endl /
      << "出错代码:" << WSAGetLastError() << endl /
      << "出错文件:" << __FILE__ << endl  /
      << "出错行数:" << __LINE__ << endl /

#define OutMsg(a) cout << (a) << endl;


/// 全局函数定义


///////////////////////////////////////////////////////////////////////
//
// 函数名       : InitWinsock
// 功能描述     : 初始化WINSOCK
// 返回值       : void
//
///////////////////////////////////////////////////////////////////////
void InitWinsock()
{
 // 初始化WINSOCK
 WSADATA wsd;
 if( WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
 {
  OutErr("WSAStartup()");
 }
}

///////////////////////////////////////////////////////////////////////
//
// 函数名       : BindServerOverlapped
// 功能描述     : 绑定端口,并返回一个 Overlapped 的Listen Socket
// 参数         : int nPort
// 返回值       : SOCKET
//
///////////////////////////////////////////////////////////////////////
SOCKET BindServerOverlapped(int nPort)
{
 // 创建socket
 SOCKET sServer = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);

 // 绑定端口
 struct sockaddr_in servAddr;
 servAddr.sin_family = AF_INET;
 servAddr.sin_port = htons(nPort);
 servAddr.sin_addr.s_addr = htonl(INADDR_ANY);

 if(bind(sServer, (struct sockaddr *)&servAddr, sizeof(servAddr)) < 0)
 {
  OutErr("bind Failed!");
  return NULL;
 }

 // 设置监听队列为200
 if(listen(sServer, 200) != 0)
 {
  OutErr("listen Failed!");
  return NULL;
 }
 return sServer;
}


/// 结构体定义
typedef struct
{
   OVERLAPPED Overlapped;
   WSABUF DataBuf;
   CHAR Buffer[DATA_BUFSIZE];
} PER_IO_OPERATION_DATA, * LPPER_IO_OPERATION_DATA;


typedef struct
{
   SOCKET Socket;
} PER_HANDLE_DATA, * LPPER_HANDLE_DATA;


DWORD WINAPI ProcessIO(LPVOID lpParam)
{
 HANDLE CompletionPort = (HANDLE)lpParam;
    DWORD BytesTransferred;
    LPPER_HANDLE_DATA PerHandleData;
    LPPER_IO_OPERATION_DATA PerIoData;

 while(true)
 {
 
  if(0 == GetQueuedCompletionStatus(CompletionPort, &BytesTransferred, (LPDWORD)&PerHandleData, (LPOVERLAPPED*)&PerIoData, INFINITE))
  {
   if( (GetLastError() == WAIT_TIMEOUT) || (GetLastError() == ERROR_NETNAME_DELETED) )
   {
    cout << "closing socket" << PerHandleData->Socket << endl;
    
    closesocket(PerHandleData->Socket);
    
    delete PerIoData;
    delete PerHandleData;
    continue;
   }
   else
   {
    OutErr("GetQueuedCompletionStatus failed!");
   }
   return 0;
  }
  
  // 说明客户端已经退出
  if(BytesTransferred == 0)
  {
   cout << "closing socket" << PerHandleData->Socket << endl;
   closesocket(PerHandleData->Socket);
   delete PerIoData;
   delete PerHandleData;
   continue;
  }

  // 取得数据并处理
  cout << PerHandleData->Socket << "发送过来的消息:" << PerIoData->Buffer << endl;

  // 继续向 socket 投递WSARecv操作
  DWORD Flags = 0;
  DWORD dwRecv = 0;
  ZeroMemory(PerIoData, sizeof(PER_IO_OPERATION_DATA));
  PerIoData->DataBuf.buf = PerIoData->Buffer;
  PerIoData->DataBuf.len = DATA_BUFSIZE;
  WSARecv(PerHandleData->Socket, &PerIoData->DataBuf, 1, &dwRecv, &Flags, &PerIoData->Overlapped, NULL); 
 }

 return 0;
}

void main()
{
 InitWinsock();

 HANDLE CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);

 // 根据系统的CPU来创建工作者线程
 SYSTEM_INFO SystemInfo;
 GetSystemInfo(&SystemInfo);

 for(int i = 0; i < SystemInfo.dwNumberOfProcessors * 2; i++)
 {
  HANDLE hProcessIO = CreateThread(NULL, 0, ProcessIO, CompletionPort, 0, NULL);
  if(hProcessIO)
  {
   CloseHandle(hProcessIO);
  }
 }

 // 创建侦听SOCKET
 SOCKET sListen = BindServerOverlapped(PORT);


 SOCKET sClient;
 LPPER_HANDLE_DATA PerHandleData;
    LPPER_IO_OPERATION_DATA PerIoData;
 while(true)
 {
  // 等待客户端接入
  //sClient = WSAAccept(sListen, NULL, NULL, NULL, 0);
  sClient = accept(sListen, 0, 0);
  
  cout << "Socket " << sClient << "连接进来" << endl;
  
  PerHandleData = new PER_HANDLE_DATA();
  PerHandleData->Socket = sClient;

  // 将接入的客户端和完成端口联系起来
  CreateIoCompletionPort((HANDLE)sClient, CompletionPort, (DWORD)PerHandleData, 0);

  // 建立一个Overlapped,并使用这个Overlapped结构对socket投递操作
  PerIoData = new PER_IO_OPERATION_DATA();
  
  ZeroMemory(PerIoData, sizeof(PER_IO_OPERATION_DATA));
  PerIoData->DataBuf.buf = PerIoData->Buffer;
  PerIoData->DataBuf.len = DATA_BUFSIZE;

  // 投递一个WSARecv操作
  DWORD Flags = 0;
  DWORD dwRecv = 0;
  WSARecv(sClient, &PerIoData->DataBuf, 1, &dwRecv, &Flags, &PerIoData->Overlapped, NULL);
 }

 DWORD dwByteTrans;
 PostQueuedCompletionStatus(CompletionPort, dwByteTrans, 0, 0);
 closesocket(sListen);
}

Windows Server 2016上,手把手教你搭建MDT 8456自动化部署环境(含ADK 2004与WDS配置) 本文详细指导在Windows Server 2016上搭建MDT 8456自动化部署环境,涵盖ADK 2004与WDS配置全流程。通过标准化操作系统部署、应用程序静默安装和驱动程序注入,实现企业级自动化部署解决方案,显著提升IT运维效率。特别针对兼容性问题和权限陷阱提供实战解决方案。 阅读详情

相关推荐

炸金花游戏(3)--基于EV(期望收益)的简单AI模型

前言:   炸金花这款游戏, 从技术的角度来说, 比德州差了很多. 所以他的AI模型也相对简单一些. 本文从EV(期望收益)的角度, 来尝试构建一个简单的炸金花AI. 相关文章:  德州扑克AI--Programming Poker AI(译).  系列文章说来惭愧, 之前一直叫嚷着写德州AI, 不过可惜懒癌晚期, 一直没去实践, T_T. 相比而言,***简单很多, 也更偏重于运...

weixin_30377461的博客 2340

WinSocket模型的探讨——完成端口模型(一)

众所皆知,完成端口是在WINDOWS平台下效率最高,扩展性最好的IO模型,特别针对于WINSOCK的海量连接时,更能显示出其威力。其实建立一个完成端口的服务器也很简单,只要注意几个函数,了解一下关键的步骤也就行了。这是篇完成端口入门级的文章,分为以下几步来说明完成端口:  函数 常见问题以及解答 步骤 例程 1、函数:我们在完成端口

一雨田的专栏 6034

嵌入式开发必备:手把手教你用DB-9连接器搞定RS-232串口通信(附万用表测试技巧)

本文详细解析了嵌入式开发中RS-232串口通信的硬件连接核心。从DB-9连接器的引脚定义入手,深入讲解DTE与DCE设备角色,明确直连线与交叉线的选择法则,并重点分享了使用万用表进行线缆连通性测试、电压测量及故障诊断的实战技巧,帮助开发者彻底掌握串口通信的硬件连接与排查方法。

tgb345678的博客 1165

 Windows socket之IO完成端口(IOCP)模型开发

Windowssocket之IO完成端口(IOCP)模型开发 IO完成端口是一种内核对象。利用完成端口,套接字应用程序能够管理数百上千个套接字。应用程序创建完成端口对象后,通过指定一定数量的服务线程,为已经完成的重叠IO操作提供服务。该模型可以达到最后的系统性能。 完成端口是一种真正意义上的异步模型。在重叠IO模型中,当Windowssocket应用程序在调用WSARecv函数后立即返回,...

系统运维 436

Vue+ECharts-GL 3D地图实战:5层叠加打造炫酷中国地图(附完整代码)

本文详细介绍了如何利用Vue和ECharts-GL构建具有强烈立体感的3D中国地图。通过5层图层的巧妙叠加与样式调校,实现了从背景阴影到交互高光的完整视觉层次,并整合了动态飞线与散点标记。文章提供了完整的代码实现、核心配置解析以及性能优化与视觉调优的实战技巧,帮助开发者快速打造专业级的交互式地图可视化应用。

d6e7f8g9h的博客 649

MD01和MD01N比较

摘要:MD01(传统MRP)与MD01N(MRP Live)是SAP系统不同版本的物料需求计划事务码。核心差异包括:MD01N取消MRP列表、简化计划规则、合并MPS/MRP操作、采用BAdI技术等,体现S/4HANA平台简化、标准化和智能化的演进方向。MD01N通过优化参数配置、增强筛选功能、利用HANA实时计算能力,实现了更高效的物料计划流程,代表了新一代计划引擎的技术革新。

SAP_LES_COM的博客 891

windows socket网络编程六:完成端口模型

文章目录分析服务器创建完成端口绑定端口与SOCKET创建线程线程内部代码投递accept、send、recv运行结果模型流程图源码链接 分析 我们的重叠IO模型还有什么问题吗? 去掉我编写时候的逻辑bug,就网络模型来说主要问题还有: 循环询问,延迟高,做了很多无用功 采用多线程,数量可能太多,我们很难管理,切换线程消耗大量cpu资源/时间 那最优线程数量是多少? 网上的几种答案: CPU核数 CPU核数*2 CPU核数*2+2 其中CPU核数*2+2 这个数量,是根据实际应用中的经验得来。线程函

c++小白的博客 2264

LBM模式学习·保姆级安装及初步使用教程

在学习LBM的过程中,我感觉可供参考的材料较为有限,对于一个独立学习LBM模式的初学者非常不友好(我就是这个初学者哈哈),因此萌生了写一篇保姆级的LBM模式教程,并将我踩过的坑一一指出,有助于后来者更快地上手该模式,而非半途而废。

weixin_42762673的博客 1万+

C++ Windows Socket五种I/O模型之完成端口模型

前面几章已经分别介绍了window下socket 网络编程的几种模式,今天简单的介绍一下最后一个模型:完成端口(completionPort)模型。 关于他的一些优点网上有一堆,这边我也不再一一介绍,点而言之就是他充分利用内核对象的调度,只使用少量的几个线程来梳理和客户端所有通信,最大限度的提高了网络通信的性能。下面简单介绍一下主要涉及主要函数。 最优线程数 根据实际应用中发现,Cup核数*2+2这个数量是最优线程数(网上查询到的,我也不知道原因),获取系统内核数可调用 VOID GetSystemInfo

weixin_45317033的博客 1778

AD9371实战:如何用ZCU106搭建JESD204B TX时钟链(含关键参数计算)

本文详细解析了如何基于Xilinx ZCU106开发板为AD9371搭建JESD204B TX时钟链。文章从系统需求出发,逐步推导出从IQ采样率到GTH线速率的关键参数计算公式,并提供了在Vivado中配置GTH收发器(包括QPLL选择、分频比设置)的实战步骤与调试技巧,旨在帮助硬件工程师快速实现稳定可靠的JESD204B高速数据传输链路。

weixin_29164843的博客 293

前端使用二开Thingsboard一、二、三事(四)-部件库

以项目实战为基础,逐步介绍前端在thingsboard系统二次开发中的一些注意事项以及一些thingsboard一些页面功能讲解,为前端人员开发使用thingsboard提供一种可靠思路,打造一个完美的物联网系统。

weixin_43163457的博客 739

【第24节】windows网络编程模型(完成端口模型)

之前讲的那些网络编程模型里,我们把“阻塞通信”和多线程搭配起来,想要解决同步模式中存在的阻碍情况。可这办法不是十全十美的。因为每来一个客户端连接,就得创建一个线程,然后在这个工作线程里处理这个客户端的各种操作。要是线程数量变得特别多,CPU就得花好多资源来来回回切换线程上下文,这样一来,CPU就没多少时间去执行工作线程里真正要做的任务了。完成端口模型就是为了解决线程上下文切换带来的这些坏处而出现的。它把内核对象的调度机制利用得很充分,只用少量线程(一般是CPU个数的2倍),就能处理和所有客户端的通信。

攻城狮7号的博客 1527

微信服务号配置总是提示“参数错误”?我就是这样一步步查出问题的

前两天,我遇到了一个很诡异的问题:在微信服务号后台配置服务器地址时,总是提示“参数错误,请重新填写”。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 1277

WinSocket模型的探讨——漫谈

SOCKET有两种模式——阻塞和非阻塞。如果使用了阻塞,在某个时间点如果出现了网络问题,一边调用recv接收不到数据的时候,那就会导致程序挂在那里!对于这个问题有两种解决的方法:一是保证使用的环境永远不会出现这种情况,二是使用多线程(就算出现了阻塞的情况也就是线程挂了,主线程还是生龙活虎的)。如果使用非阻塞的SOCKET,我们需要不断的去轮询看recv/send函数是否成功,如果不成功,我

一雨田的专栏 4114

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

WinSocket模型的探讨——select模型

查找了很多资料都找不到select模型的详细用法,《Windows网络编程》这本书上也只是写了一个简单的回应服务器,就连writefds的用法都没讲,也不知道什么时候利用“可写”来发文件。这些都是我的疑问,相信很多研究网络编程的同路人也碰到了我的这些问题。这些疑问在这篇文章中都解决了!耗费了偶很多的精力去猜测去思考! 感觉一些已经得道的高人都不肯把这些问题说透彻点,唉,只能靠自己去摸索了,希望

tony的专栏 775

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

上一篇: WSARecv参数lpNumberOfBytesRecvd的一个变态问题
下一篇: 研究飞鸽传书
普通网友
博客等级 码龄22年 1万+粉丝 3156原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值