📄 layernet.c~
字号:
/******************************************************************************//* *//* LAYERNET - All principal routines for LayerNet processing *//* *//* Copyright (c) 1993 by Academic Press, Inc. *//* *//* All rights reserved. Permission is hereby granted, until further notice, *//* to make copies of this diskette, which are not for resale, provided these *//* copies are made from this master diskette only, and provided that the *//* following copyright notice appears on the diskette label: *//* (c) 1993 by Academic Press, Inc. *//* *//* Except as previously stated, no part of the computer program embodied in *//* this diskette may be reproduced or transmitted in any form or by any means,*//* electronic or mechanical, including input into storage in any information *//* system for resale, without permission in writing from the publisher. *//* *//* Produced in the United States of America. *//* *//* ISBN 0-12-479041-0 *//* *//******************************************************************************/#include <stdio.h>#include <string.h>#include <math.h>#include <ctype.h>#include <stdlib.h>#include "const.h" // System and limitation constants, typedefs, structs#include "classes.h" // Includes all class headers#include "funcdefs.h" // Function prototypesstatic void free_non_null ( void **p ) ;/*-------------------------------------------------------------------------------- Constructor The parameter 'executable' determines whether work areas for hidden and output neuron activations are also allocated. These are needed if we will ever apply inputs and want to compute outputs. In case of malloc failure, we set 'ok' to zero so the user knows about it. Also, we always leave unallocated weight pointers set to NULL. There is no hard reason for doing this; calling programs should always know enough not to reference them. However, it is simply good style. Most compilers are much better at producing code that intercepts NULL pointer references than just wild pointers. An ounce of prevention...--------------------------------------------------------------------------------*/LayerNet::LayerNet ( int out_model , int n_inputs , int n_hidden1 , int n_hidden2 , int n_outputs , int executable , // Also allocate hidden and output neurons? int zero // Zero all weights? ){ int i, n1, n2, n3 ; outmod = out_model ; nin = n_inputs ; nhid1 = n_hidden1 ; nhid2 = n_hidden2 ; nout = n_outputs ; exe = executable ; neterr = 1.0 ; confusion = NULL ; hid1_coefs = hid2_coefs = out_coefs = hid1 = hid2 = out = NULL ; ok = 0 ; // Indicates failure of malloc (What a pessimist!) if (exe && (confusion = (int *) MALLOC ( (nout+1) * sizeof(int))) == NULL) return ; if (nhid1 == 0) { // No hidden layer n1 = nout * (nin+1) ; if (((out_coefs = (double *) MALLOC ( n1 * sizeof(double) )) == NULL) || (exe && (out = (double *) MALLOC ( nout * sizeof(double) )) == NULL)){ free_non_null ( (void **) &out_coefs ) ; free_non_null ( (void **) &confusion ) ; return ; } if (zero) { while (n1--) out_coefs[n1] = 0.0 ; } } else if (nhid2 == 0) { // One hidden layer n1 = nhid1 * (nin+1) ; n2 = nout * (nhid1+1) ; if (((hid1_coefs = (double *) MALLOC ( n1 * sizeof(double) )) == NULL) || ((out_coefs = (double *) MALLOC ( n2 * sizeof(double) ))==NULL) || (exe && (hid1 = (double *) MALLOC ( nhid1 * sizeof(double) ))==NULL) || (exe && (out = (double *) MALLOC ( nout * sizeof(double) )) == NULL)){ free_non_null ( (void **) &hid1_coefs ) ; free_non_null ( (void **) &out_coefs ) ; free_non_null ( (void **) &hid1 ) ; free_non_null ( (void **) &confusion ) ; return ; } if (zero) { while (n1--) hid1_coefs[n1] = 0.0 ; while (n2--) out_coefs[n2] = 0.0 ; } } else { // Two hidden layers n1 = nhid1 * (nin+1) ; n2 = nhid2 * (nhid1+1) ; n3 = nout * (nhid2+1) ; if (((hid1_coefs = (double *) MALLOC ( n1 * sizeof(double) )) == NULL) || ((hid2_coefs = (double *) MALLOC ( n2 * sizeof(double) )) == NULL) || ((out_coefs = (double *) MALLOC ( n3 * sizeof(double) ))==NULL) || (exe && (hid1 = (double *) MALLOC ( nhid1 * sizeof(double) ))==NULL) || (exe && (hid2 = (double *) MALLOC ( nhid2 * sizeof(double) ))==NULL) || (exe && (out = (double *) MALLOC ( nout * sizeof(double) )) == NULL)){ free_non_null ( (void **) &hid1_coefs ) ; free_non_null ( (void **) &hid2_coefs ) ; free_non_null ( (void **) &out_coefs ) ; free_non_null ( (void **) &hid1 ) ; free_non_null ( (void **) &hid2 ) ; free_non_null ( (void **) &confusion ) ; return ; } if (zero) { while (n1--) hid1_coefs[n1] = 0.0 ; while (n2--) hid2_coefs[n2] = 0.0 ; while (n3--) out_coefs[n3] = 0.0 ; } } if (exe) memset ( confusion , 0 , (nout+1) * sizeof(int) ) ; ok = 1 ; // Indicate to caller that all mallocs succeeded}/* Local routine to free non-null pointers*/static void free_non_null ( void **p ){ if (*p != NULL) { FREE ( *p ) ; *p = NULL ; }}/*-------------------------------------------------------------------------------- Destructor--------------------------------------------------------------------------------*/LayerNet::~LayerNet(){ if (! ok) // If constructor's mallocs failed return ; // there is nothing to free FREE ( out_coefs ) ; if (exe) { FREE ( out ) ; FREE ( confusion ) ; } if (nhid1) { FREE ( hid1_coefs ) ; if (exe) FREE ( hid1 ) ; if (nhid2) { FREE ( hid2_coefs ) ; if (exe) FREE ( hid2 ) ; } }}/*-------------------------------------------------------------------------------- copy_weights - Copy the weights from one network to another Note that this is NOT like a copy or assignment, as it does not copy other parameters. In fact, it gets sizes from the calling instance!--------------------------------------------------------------------------------*/void LayerNet::copy_weights ( LayerNet *dest , LayerNet *source ){ int n ; dest->neterr = source->neterr ; if (source->exe && dest->exe) // These may be important too! memcpy ( dest->confusion , source->confusion , (nout+1) * sizeof(int) ) ; if (nhid1 == 0) { // No hidden layer n = nout * (nin+1) ; memcpy ( dest->out_coefs , source->out_coefs , n * sizeof(double) ) ; } else if (nhid2 == 0) { // One hidden layer n = nhid1 * (nin+1) ; memcpy ( dest->hid1_coefs , source->hid1_coefs , n * sizeof(double) ) ; n = nout * (nhid1+1) ; memcpy ( dest->out_coefs , source->out_coefs , n * sizeof(double) ) ; } else { // Two hidden layers n = nhid1 * (nin+1) ; memcpy ( dest->hid1_coefs , source->hid1_coefs , n * sizeof(double) ) ; n = nhid2 * (nhid1+1) ; memcpy ( dest->hid2_coefs , source->hid2_coefs , n * sizeof(double) ) ; n = nout * (nhid2+1) ; memcpy ( dest->out_coefs , source->out_coefs , n * sizeof(double) ) ; }}/*-------------------------------------------------------------------------------- zero_weights - Zero all weights in a network--------------------------------------------------------------------------------*/void LayerNet::zero_weights (){ int n ; neterr = 1.0 ; if (nhid1 == 0) { // No hidden layer n = nout * (nin+1) ; while (n--) out_coefs[n] = 0.0 ; } else if (nhid2 == 0) { // One hidden layer n = nhid1 * (nin+1) ; while (n--) hid1_coefs[n] = 0.0 ; n = nout * (nhid1+1) ; while (n--) out_coefs[n] = 0.0 ; } else { // Two hidden layers n = nhid1 * (nin+1) ; while (n--) hid1_coefs[n] = 0.0 ; n = nhid2 * (nhid1+1) ; while (n--) hid2_coefs[n] = 0.0 ; n = nout * (nhid2+1) ; while (n--) out_coefs[n] = 0.0 ; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -