对代码进行了一下修改https://github.com/aitazhixin/DL/tree/master/AlexNet,目前的运行效率比较低,准备采用多线程的方式实现一下。
根据原文,所有卷积层和池化层采用了ReLU激活函数,激活函数的导数为0或1(激活值非0时)。第三卷积层和第一、第二全连接层使用了Dropout方式。没有采用原文使用的LRN技术,采用了最大池化。在ImageNet2012数据集中选取了10类图片进行训练,但是迭代的效果不好。贴出代码希望集思广益,希望高手拔刀相助。
一些初始化或者辅助接口:
slqAlexNet::~slqAlexNet()
{
if (inRaw)
{
delete inRaw;
inRaw = nullptr;
}
deletevar(&mlabel);
deletevar(&inMap);
deletevar(&c1Map);
deletevar(&s1Map);
deletevar(&c2Map);
deletevar(&s2Map);
deletevar(&c3Map);
deletevar(&c4Map);
deletevar(&c5Map);
deletevar(&s5Map);
deletevar(&f1Map);
deletevar(&f2Map);
deletevar(&f3Map);
deletevar(&c1Conv);
deletevar(&s1Pool);
deletevar(&c2Conv);
deletevar(&s2Pool);
deletevar(&c3Conv);
deletevar(&c4Conv);
deletevar(&c5Conv);
deletevar(&s5Pool);
deletevar(&f1Conn);
deletevar(&f2Conn);
deletevar(&f3Conn);
deletevar(&c1Bias);
deletevar(&s1Bias);
deletevar(&c2Bias);
deletevar(&s2Bias);
deletevar(&c3Bias);
deletevar(&c4Bias);
deletevar(&c5Bias);
deletevar(&s5Bias);
deletevar(&f1Bias);
deletevar(&f2Bias);
deletevar(&f3Bias);
deletevar(&c1MapDt);
deletevar(&s1MapDt);
deletevar(&c2MapDt);
deletevar(&s2MapDt);
deletevar(&c3MapDt);
deletevar(&c4MapDt);
deletevar(&c5MapDt);
deletevar(&s5MapDt);
deletevar(&f1MapDt);
deletevar(&f2MapDt);
deletevar(&f3MapDt);
deletevar(&c1ConvDt);
deletevar(&s1PoolDt);
deletevar(&c2ConvDt);
deletevar(&s2PoolDt);
deletevar(&c3ConvDt);
deletevar(&c4ConvDt);
deletevar(&c5ConvDt);
deletevar(&s5PoolDt);
deletevar(&f1ConnDt);
deletevar(&f2ConnDt);
deletevar(&f3ConnDt);
deletevar(&c1BiasDt);
deletevar(&s1BiasDt);
deletevar(&c2BiasDt);
deletevar(&s2BiasDt);
deletevar(&c3BiasDt);
deletevar(&c4BiasDt);
deletevar(&c5BiasDt);
deletevar(&s5BiasDt);
deletevar(&f1BiasDt);
deletevar(&f2BiasDt);
deletevar(&f3BiasDt);
deletevar(&c1ConvEDt);
deletevar(&s1PoolEDt);
deletevar(&c2ConvEDt);
deletevar(&s2PoolEDt);
deletevar(&c3ConvEDt);
deletevar(&c4ConvEDt);
deletevar(&c5ConvEDt);
deletevar(&s5PoolEDt);
deletevar(&f1ConnEDt);
deletevar(&f2ConnEDt);
deletevar(&f3ConnEDt);
deletevar(&c1BiasEDt);
deletevar(&s1BiasEDt);
deletevar(&c2BiasEDt);
deletevar(&s2BiasEDt);
deletevar(&c3BiasEDt);
deletevar(&c4BiasEDt);
deletevar(&c5BiasEDt);
deletevar(&s5BiasEDt);
deletevar(&f1BiasEDt);
deletevar(&f2BiasEDt);
deletevar(&f3BiasEDt);
}
void slqAlexNet::init()
{
initParm();
}
void slqAlexNet::CreateConv3Table()
{
int oIdx;
int iIdx;
#define AO true
#define AX false
for (oIdx = 0; oIdx < c3ConvNum; oIdx++)
{
for (iIdx = 0; iIdx < c3ConvDeep; iIdx++)
{
if ((oIdx >= iIdx) && (oIdx < iIdx + c3ConvDeep/2))
{
CONV3Table[oIdx][iIdx] = AX;
continue;
}
CONV3Table[oIdx][iIdx] = AO;
}
}
for (oIdx = 0; oIdx < s5UnitNum; oIdx++)
{
for (iIdx = 0; iIdx < f1UnitNum; iIdx++)
{
if ((oIdx >= iIdx) && (oIdx < iIdx + f1UnitNum/2))
{
F1Table[oIdx][iIdx] = AX;
continue;
}
F1Table[oIdx][iIdx] = AO;
}
}
for (oIdx = 0; oIdx < f1UnitNum; oIdx++)
{
for (iIdx = 0; iIdx < f2UnitNum; iIdx++)
{
if ((oIdx >= iIdx) && (oIdx < iIdx + f2UnitNum/2))
{
F2Table[oIdx][iIdx] = AX;
continue;
}
F2Table[oIdx][iIdx] = AO;
}
}
#undef AO
#undef AX
}
void slqAlexNet::deletevar(float **var)
{
if (nullptr != *var)
{
delete *var;
*var = nullptr;
}
}
void slqAlexNet::initParm()
{
newParam();
// all weights follow gauss distribution
uniform_rand(c1Conv, c1ConvUNum, 0.f, 0.f);
uniform_rand(s1Pool, s1MapNum, 0.f, 0.f);
uniform_rand(c2Conv, c2ConvUNum, 0.f, 0.f);
uniform_rand(s2Pool, s2MapNum, 0.f, 0.f);
uniform_rand(c3Conv, c3ConvUNum, 0.f, 0.f);
uniform_rand(c4Conv, c4ConvUNum, 0.f, 0.f);
uniform_rand(c5Conv, c5ConvUNum, 0.f, 0.f);
uniform_rand(s5Pool, s5MapNum, 0.f, 0.f);
uniform_rand(f1Conn, f1ConnNum, 0.f, 0.f);
uniform_rand(f2Conn, f2ConnNum, 0.f, 0.f);
uniform_rand(f3Conn, f3ConnNum, 0.f, 0.f);
// 2th, 4th, 5th conv bias set to 1
std::fill(c2Bias, c2Bias + c2MapNum, 1.0f);
std::fill(c4Bias, c4Bias + c4MapNum, 1.0f);
std::fill(c5Bias, c5Bias + c5MapNum, 1.0f);
}
void slqAlexNet::newParam()
{
mlabel = new float[f3UnitNum]();
inRaw = new char[inUnitNum]();
inMap = new float[inUnitNum]();
c1Map = new float[c1UnitNum]();
s1Map = new float[s1UnitNum]();
c2Map = new float[c2UnitNum]();
s2Map = new float[s2UnitNum]();
c3Map = new float[c3UnitNum]();
c4Map = new float[c4UnitNum]();
c5Map = new float[c5UnitNum]();
s5Map = new float[s5UnitNum]();
f1Map = new float[f1UnitNum]();
f2Map = new float[f2UnitNum]();
f3Map = new float[f3UnitNum]();
c1Conv = new float[c1ConvUNum]();
s1Pool = new float[s1MapNum]();
c2Conv = new float[c2ConvUNum]();
s2Pool = new float[s2MapNum]();
c3Conv = new float[c3ConvUNum]();
c4Conv = new float[c4ConvUNum]();
c5Conv = new float[c5ConvUNum]();
s5Pool = new float[s5MapNum]();
f1Conn = new float[f1ConnNum]();
f2Conn = new float[f2ConnNum]();
f3Conn = new float[f3ConnNum]();
c1Bias = new float[c1MapNum]();
s1Bias = new float[s1MapNum]();
c2Bias = new float[c2MapNum]();
s2Bias = new float[s2MapNum]();
c3Bias = new float[c3MapNum]();
c4Bias = new float[c4MapNum]();
c5Bias = new float[c5MapNum]();
s5Bias = new float[s5MapNum]();
f1Bias = new float[f1UnitNum]();
f2Bias = new float[f2UnitNum]();
f3Bias = new float[f3UnitNum]();
c1MapDt = new float[c1UnitNum]();
s1MapDt = new float[s1UnitNum]();
c2MapDt = new float[c2UnitNum]();
s2MapDt = new float[s2UnitNum]();
c3MapDt = new float[c3UnitNum]();
c4MapDt = new float[c4UnitNum]();
c5MapDt = new float[c5UnitNum]();
s5MapDt = new float[s5UnitNum]();
f1MapDt = new float[f1UnitNum]();
f2MapDt = new float[f2UnitNum]();
f3MapDt = new float[f3UnitNum]();
c1ConvDt = new float[c1ConvUNum]();
s1PoolDt = new float[s1MapNum]();
c2ConvDt = new float[c2ConvUNum]();
s2PoolDt = new float[s2MapNum]();
c3ConvDt = new float[c3ConvUNum]();
c4ConvDt = new float[c4ConvUNum]();
c5ConvDt = new float[c5ConvUNum]();
s5PoolDt = new float[s5MapNum]();
f1ConnDt = new float[f1ConnNum]();
f2ConnDt = new float[f2ConnNum]();
f3ConnDt = new float[f3ConnNum]();
c1BiasDt = new float[c1MapNum]();
s1BiasDt = new float[s1MapNum]();
c2BiasDt = new float[c2MapNum]();
s2BiasDt = new float[s2MapNum]();
c3BiasDt = new float[c3MapNum]();
c4BiasDt = new float[c4MapNum]();
c5BiasDt = new float[c5MapNum]();
s5BiasDt = new float[s5MapNum]();
f1BiasDt = new float[f1UnitNum]();
f2BiasDt = new float[f2UnitNum]();
f3BiasDt = new float[f3UnitNum]();
c1ConvEDt = new float[c1ConvUNum]();
s1PoolEDt = new float[s1MapNum]();
c2ConvEDt = new float[c2ConvUNum]();
s2PoolEDt = new float[s2MapNum]();
c3ConvEDt = new float[c3ConvUNum]();
c4ConvEDt = new float[c4ConvUNum]();
c5ConvEDt = new float[c5ConvUNum]();
s5PoolEDt = new float[s5MapNum]();
f1ConnEDt = new float[f1ConnNum]();
f2ConnEDt = new float[f2ConnNum]();
f3ConnEDt = new float[f3ConnNum]();
c1BiasEDt = new float[c1MapNum]();
s1BiasEDt = new float[s1MapNum]();
c2BiasEDt = new float[c2MapNum]();
s2BiasEDt = new float[s2MapNum]();
c3BiasEDt = new float[c3MapNum]();
c4BiasEDt = new float[c4MapNum]();
c5BiasEDt = new float[c5MapNum]();
s5BiasEDt = new float[s5MapNum]();
f1BiasEDt = new float[f1UnitNum]();
f2BiasEDt = new float[f2UnitNum]();
f3BiasEDt = new float[f3UnitNum]();
}
void slqAlexNet::UpgradeNetwork()
{
UpdateParameters(c1ConvDt, c1ConvEDt, c1Conv, c1ConvUNum);
UpdateParameters(c1BiasDt, c1BiasEDt, c1Bias, c1MapNum);
UpdateParameters(s1PoolDt, s1PoolEDt, s1Pool, s1MapNum);
UpdateParameters(s1BiasDt, s1BiasEDt, s1Bias, s1MapNum);
UpdateParameters(c2ConvDt, c2ConvEDt, c2Conv, c2ConvUNum);
UpdateParameters(c2BiasDt, c2BiasEDt, c2Bias, c2MapNum);
UpdateParameters(s2PoolDt, s2PoolEDt, s2Pool, s2MapNum);
UpdateParameters(s2BiasDt, s2BiasEDt, s2Bias, s2MapNum);
UpdateParameters(c3ConvDt, c3ConvEDt, c3Conv, c3ConvUNum);
UpdateParameters(c3BiasDt, c3BiasEDt, c3Bias, c3MapNum);
UpdateParameters(c4ConvDt, c4ConvEDt, c4Conv, c4ConvUNum);
UpdateParameters(c4BiasDt, c4BiasEDt, c4Bias, c4MapNum);
UpdateParameters(c5ConvDt, c5ConvEDt, c5Conv, c5ConvUNum);
UpdateParameters(c5BiasDt, c5BiasEDt, c5Bias, c5MapNum);
UpdateParameters(s5PoolDt, s5PoolEDt, s5Pool, s5MapNum);
UpdateParameters(s5BiasDt, s5BiasEDt, s5Bias, s5MapNum);
UpdateParameters(f1ConnDt, f1ConnEDt, f1Conn, f1ConnNum);
UpdateParameters(f1BiasDt, f1BiasEDt, f1Bias, f1UnitNum);
UpdateParameters(f2ConnDt, f2ConnEDt, f2Conn, f2ConnNum);
UpdateParameters(f2BiasDt, f2BiasEDt, f2Bias, f2UnitNum);
UpdateParameters(f3ConnDt, f3ConnEDt, f3Conn, f3ConnNum);
UpdateParameters(f3BiasDt, f3BiasEDt, f3Bias, f3UnitNum);
}
void slqAlexNet::UpdateParameters(float *delta, float *Edelta, float *para, int len)
{
for (int lIdx = 0; lIdx < len; lIdx++)
{
Edelta[lIdx] = 0.9f * Edelta[lIdx] - 0.0005 * Alpha * delta[lIdx];
para[lIdx] += Edelta[lIdx];
}
}
void slqAlexNet::ConvolutionOpt(float *inPtr, float *outPtr, float *convPtr, float *biPtr, int param[])
{
int inMapNo = param[0];
int outMapNo = param[1];
int inMapH = param[2];
int inMapW = param[3];
int outMapH = param[4];
int outMapW = param[5];
int convH = param[6];
int convW = param[7];
int convStride = param[8];
int expand = param[9];
int odeepIdx;
int ideepIdx;
int ohIdx;
int owIdx;
int phIdx;
int pwIdx;
int iod;
int vod;
int svh;
int insize = inMapH * inMapW;
int convsize = inMapNo * convH * convW;
int convtsor = convH * convW;
for (odeepIdx = 0; odeepIdx < outMapNo; odeepIdx++)
{
for (ohIdx = expand; ohIdx < outMapH - expand; ohIdx++)
{
iod = odeepIdx * outMapH * outMapW + ohIdx * outMapW;
for (owIdx = expand; owIdx < outMapW - expand; owIdx++)
{
float *curmap = outPtr + iod + owIdx;
float cur = 0.f;
for (ideepIdx = 0; ideepIdx < inMapNo; ideepIdx++)
{
if ((inMapNo == s2MapNum) && (outMapNo == c3MapNum) && (!CONV3Table[odeepIdx][ideepIdx]))
continue;
vod = odeepIdx * convsize + ideepIdx * convtsor;
svh = ideepIdx * insize + (ohIdx - expand) * convStride * inMapW + (owIdx - expand) * convStride;
float *curcv = convPtr + vod;
float *curin = inPtr + svh;
for (phIdx = 0; phIdx < convH; phIdx++)
{
for (pwIdx = 0; pwIdx < convW; pwIdx++)
{
cur += *(curcv + phIdx * convW + pwIdx) * (*(curin + phIdx * inMapW + pwIdx));
}
}
}
*curmap = cur + *(biPtr + odeepIdx);
*curmap = ACTIVATION(*curmap);
}
}
}
}
void slqAlexNet::PoolingOpt(float *inPtr, float *outPtr, float *poolPtr, float *biPtr, int param[])
{
int mapNo = param[0];
int imapH = param[1];
int imapW = param[2];
int omapH = param[3];
int omapW = param[4];
int poolspace = param[5];
int poolstride = param[6];
int expand = param[7];
int deepIdx;
int ohIdx;
int owIdx;
int phIdx;
int pwIdx;
int iod;
int vod;
for(deepIdx = 0; deepIdx < mapNo; deepIdx++)
{
for (ohIdx = expand; ohIdx < omapH - expand; ohIdx++)
{
iod = deepIdx * omapH * omapW + ohIdx * omapW;
for (owIdx = expand; owIdx < omapW - expand; owIdx++)
{
vod = deepIdx * imapH * imapW + (ohIdx - expand) * poolstride * imapW + (owIdx - expand) * poolstride;
float *curmap = outPtr + iod + owIdx;
float *curin = inPtr + vod;
float cur = FLT_MIN;
for (phIdx = 0; phIdx < poolspace; phIdx++)
{
for (pwIdx = 0; pwIdx < poolspace; pwIdx++)
{
//cur += *(curin + phIdx * imapW + pwIdx);
cur = cur >(*(curin + phIdx * imapW + pwIdx)) ? cur : (*(curin + phIdx * imapW + pwIdx));
}
}
//*curmap = cur / (poolspace * poolspace) + *(biPtr + deepIdx);
*curmap = cur + *(biPtr + deepIdx);
*curmap = ACTIVATION(*curmap);
}
}
}
}
void slqAlexNet::SaveParameters()
{
ofstream fileStream;
fileStream.open("alexParams", ofstream::out | ofstream::binary);
if (!fileStream)
{
cout << "Error to create Parameters file" << endl;
return;
}
fileStream.write((char*)c1Conv, c1ConvUNum * sizeof(float));
fileStream.write((char*)c1BiasDt, c1MapNum * sizeof(float));
fileStream.write((char*)s1PoolDt, s1MapNum * sizeof(float));
fileStream.write((char*)s1BiasDt, s1MapNum * sizeof(float));
fileStream.write((char*)c2ConvDt, c2ConvUNum * sizeof(float));
fileStream.write((char*)c2BiasDt, c2MapNum * sizeof(float));
fileStream.write((char*)s2PoolDt, s2MapNum * sizeof(float));
fileStream.write((char*)s2BiasDt, s2MapNum * sizeof(float));
fileStream.write((char*)c3ConvDt, c3ConvUNum * sizeof(float));
fileStream.write((char*)c3BiasDt, c3MapNum * sizeof(float));
fileStream.write((char*)c4ConvDt, c4ConvUNum * sizeof(float));
fileStream.write((char*)c4BiasDt, c4MapNum * sizeof(float));
fileStream.write((char*)c5ConvDt, c5ConvUNum * sizeof(float));
fileStream.write((char*)c5BiasDt, c5MapNum * sizeof(float));
fileStream.write((char*)s5PoolDt, s5MapNum * sizeof(float));
fileStream.write((char*)s5BiasDt, s5MapNum * sizeof(float));
fileStream.write((char*)f1ConnDt, f1ConnNum * sizeof(float));
fileStream.write((char*)f1BiasDt, f1UnitNum * sizeof(float));
fileStream.write((char*)f2ConnDt, f2ConnNum * sizeof(float));
fileStream.write((char*)f2BiasDt, f2UnitNum * sizeof(float));
fileStream.write((char*)f3ConnDt, f3ConnNum * sizeof(float));
fileStream.write((char*)f3BiasDt, f3UnitNum * sizeof(float));
}
void slqAlexNet::ReadParameters()
{
ifstream fileStream;
fileStream.open("alexParams", ifstream::in | ifstream::binary);
if (!fileStream)
{
cout << "Error to Open Params file" << endl;
return;
}
fileStream.read((char*)c1Conv, c1ConvUNum * sizeof(float));
fileStream.read((char*)c1BiasDt, c1MapNum * sizeof(float));
fileStream.read((char*)s1PoolDt, s1MapNum * sizeof(float));
fileStream.read((char*)s1BiasDt, s1MapNum * sizeof(float));
fileStream.read((char*)c2ConvDt, c2ConvUNum * sizeof(float));
fileStream.read((char*)c2BiasDt, c2MapNum * sizeof(float));
fileStream.read((char*)s2PoolDt, s2MapNum * sizeof(float));
fileStream.read((char*)s2BiasDt, s2MapNum * sizeof(float));
fileStream.read((char*)c3ConvDt, c3ConvUNum * sizeof(float));
fileStream.read((char*)c3BiasDt, c3MapNum * sizeof(float));
fileStream.read((char*)c4ConvDt, c4ConvUNum * sizeof(float));
fileStream.read((char*)c4BiasDt, c4MapNum * sizeof(float));
fileStream.read((char*)c5ConvDt, c5ConvUNum * sizeof(float));
fileStream.read((char*)c5BiasDt, c5MapNum * sizeof(float));
fileStream.read((char*)s5PoolDt, s5MapNum * sizeof(float));
fileStream.read((char*)s5BiasDt, s5MapNum * sizeof(float));
fileStream.read((char*)f1ConnDt, f1ConnNum * sizeof(float));
fileStream.read((char*)f1BiasDt, f1UnitNum * sizeof(float));
fileStream.read((char*)f2ConnDt, f2ConnNum * sizeof(float));
fileStream.read((char*)f2BiasDt, f2UnitNum * sizeof(float));
fileStream.read((char*)f3ConnDt, f3ConnNum * sizeof(float));
fileStream.read((char*)f3BiasDt, f3UnitNum * sizeof(float));
}
void slqAlexNet::RandomBias(float *randVector, int vLen)
{}
void slqAlexNet::ProduceLabel()
{
int lIdx;
for (lIdx = 0; lIdx < f3UnitNum; lIdx++)
{
if (curLabl == lIdx)
{
mlabel[lIdx] = 0.8f;
}
else
{
mlabel[lIdx] = -0.8f;
}
}
}
void slqAlexNet::RegularMap(char *cmap, float *mapdata)
{
int mIdx;
float maxv = -10.f;
float minv = 256.f;
char *curc = cmap;
float *curmap = mapdata;
for (mIdx = 0; mIdx < inMapSize; mIdx++)
{
float cur = curc[mIdx] < 0 ? (curc[mIdx] + 256.f) : curc[mIdx];
maxv = cur > maxv ? cur : maxv;
minv = cur < minv ? cur : minv;
}
for (mIdx = 0; mIdx < inMapSize; mIdx++)
{
float cur = curc[mIdx] < 0 ? (curc[mIdx] + 256.f) : curc[mIdx];
curmap[mIdx] = (cur - minv) / (maxv - minv) * 2.f - 1.f;
}
maxv = -10.f;
minv = 256.f;
curc = cmap + inMapSize;
curmap = mapdata + inMapSize;
for (mIdx = 0; mIdx < inMapSize; mIdx++)
{
float cur = curc[mIdx] < 0 ? (curc[mIdx] + 256.f) : curc[mIdx];
maxv = cur > maxv ? cur : maxv;
minv = cur < minv ? cur : minv;
}
for (mIdx = 0; mIdx < inMapSize; mIdx++)
{
float cur = curc[mIdx] < 0 ? (curc[mIdx] + 256.f) : curc[mIdx];
curmap[mIdx] = (cur - minv) / (maxv - minv) * 2.f - 1.f;
}
maxv = -10.f;
minv = 256.f;
curc = cmap + inMapSize*2;
curmap = mapdata + inMapSize*2;
for (mIdx = 0; mIdx < inMapSize; mIdx++)
{
float cur = curc[mIdx] < 0 ? (curc[mIdx] + 256.f) : curc[mIdx];
maxv = cur > maxv ? cur : maxv;
minv = cur < minv ? cur : minv;
}
for (mIdx = 0; mIdx < inMapSize; mIdx++)
{
float cur = curc[mIdx] < 0 ? (curc[mIdx] + 256.f) : curc[mIdx];
curmap[mIdx] = (cur - minv) / (maxv - minv) * 2.f - 1.f;
}
}
void slqAlexNet::uniform_rand(float* src, int len, float min, float max)
{
int rIdx = 0;
for (; rIdx < len; rIdx++)
{
src[rIdx] = uniform_rand(min, max);
}
}
float slqAlexNet::uniform_rand(float min, float max)
{
static float U, V;
static int phase = 0;
float gaussz = 0;
if (0 == phase)
{
U = (rand() + EspCNN) / (RAND_MAX + 1.0f);
V = (rand() + EspCNN) / (RAND_MAX + 1.0f);
gaussz = 0.01f * std::sqrt(-2.0f * log(U)) * sin(2.0f * CV_PI * V);
}
else
{
gaussz = 0.01f * std::sqrt(-2.0f * log(U)) * cos(2.0f * CV_PI * V);
}
phase = 1 - phase;
return gaussz;
}
训练接口:
void slqAlexNet::train()
{
int epo;
int ipo = 0;
float acc = 0.0f;
ifstream trainStream;
ifstream trainlabel;
for (epo = 0; epo < EpochLoop; epo++)
{
trainStream.open("imgTrainArray", ifstream::in | ifstream::binary);
trainlabel.open("imgTrainLabel", ifstream::in | ifstream::binary);
if ((!trainStream) || (!trainlabel))
{
if (trainStream)
trainStream.close();
if (trainlabel)
trainlabel.close();
cout << "There does not exist train data" << endl;
return;
}
while (EOF != trainStream.peek())
{
trainStream.read(inRaw, sizeof(char)*inUnitNum);
trainlabel.read(&curLabl, sizeof(char));
//Mat img(227, 227, CV_8UC1);
//memcpy((char*)img.data, inRaw, 227*227);
//cv::namedWindow("inRaw");
//cv::imshow("inRaw", img);
//cv::waitKey(0);
//memcpy((char*)img.data, inRaw + 227*227, 227 * 227);
//cv::namedWindow("inRaw");
//cv::imshow("inRaw", img);
//cv::waitKey(0);
//memcpy((char*)img.data, inRaw + 227*227*2, 227 * 227);
//cv::namedWindow("inRaw");
//cv::imshow("inRaw", img);
//cv::waitKey(0);
ProduceLabel();
RegularMap(inRaw, inMap);
ForwardC1();
ForwardS1();
ForwardC2();
ForwardS2();
ForwardC3();
ForwardC4();
ForwardC5();
ForwardS5();
ForwardF1();
ForwardF2();
ForwardF3();
BackwardF3();
BackwardF2();
BackwardF1();
BackwardS5();
BackwardC5();
BackwardC4();
BackwardC3();
BackwardS2();
BackwardC2();
BackwardS1();
BackwardC1();
UpgradeNetwork();
ipo++;
}
trainlabel.close();
trainStream.close();
acc = test();
cout << "epoch " << epo << " accuracy " << acc << endl;
if (acc >= AccuracyRate)
{
cout << "Save Params ..." << endl;
SaveParameters();
}
else if (acc < 0)
{
return;
}
}
if (EpochLoop == epo)
{
cout << "End loop, Save Params" << endl;
SaveParameters();
}
}
验证接口:
float slqAlexNet::test()
{
float acc = 0.f;
float prc = 0.f;
float maxv = -10.f;
int maxI;
char tlabl;
int mIdx;
int count = 0;
ifstream testStream;
ifstream testlabl;
testStream.open("imgTestArray", ifstream::in | ifstream::binary);
testlabl.open("imgTestLabel", ifstream::in | ifstream::binary);
if ((!testStream) || !testlabl)
{
if (testStream)
testStream.close();
if (testlabl)
testlabl.close();
cout << "There does not exist test data" << endl;
return -1.f;
}
while (EOF != testStream.peek())
{
count++;
testStream.read(inRaw, sizeof(char)* inUnitNum);
testlabl.read(&tlabl, sizeof(char));
RegularMap(inRaw, inMap);
ForwardC1();
ForwardS1();
ForwardC2();
ForwardS2();
ForwardC3();
ForwardC4();
ForwardC5();
ForwardS5();
ForwardF1();
ForwardF2();
ForwardF3();
for (mIdx = 0; mIdx < f3UnitNum; mIdx++)
{
maxI = f3Map[mIdx] > maxv ? mIdx : maxI;
maxv = f3Map[mIdx] > maxv ? f3Map[mIdx] : maxv;
}
if (maxI == tlabl)
prc += 1;
}
testStream.close();
testlabl.close();
return (prc / count);
}
前向运算:
void slqAlexNet::ForwardC1()
{
int params[] = {inMapNum, c1MapNum, inMapHigh, inMapWidth, c1MapHigh, c1MapWidth, c1ConvHigh, c1ConvWidth, c1ConvStride, 0 };
std::fill(c1Map, c1Map + c1UnitNum, 0.f);
ConvolutionOpt(inMap, c1Map, c1Conv, c1Bias, params);
}
void slqAlexNet::ForwardS1()
{
int params[] = {s1MapNum, c1MapHigh, c1MapWidth, s1MapHigh, s1MapWidth, poolSpace, poolStride, 2};
float tmp[c1UnitNum];
memcpy((char*)tmp, (char*)c1Map, sizeof(float)*c1UnitNum);
std::fill(s1Map, s1Map + s1UnitNum, 0.f);
PoolingOpt(c1Map, s1Map, s1Pool, s1Bias, params);
}
void slqAlexNet::ForwardC2()
{
int params[] = { s1MapNum / 2, c2MapNum / 2, s1MapHigh, s1MapWidth, c2MapHigh, c2MapWidth, c2ConvHigh, c2ConvWidth, c2ConvStride, 0 };
float tmp[s1UnitNum];
memcpy((char*)tmp, (char*)s1Map, sizeof(float)*s1UnitNum);
std::fill(c2Map, c2Map + c2UnitNum, 0.f);
ConvolutionOpt(s1Map, c2Map, c2Conv, c2Bias, params);
ConvolutionOpt(s1Map + s1MapNum / 2 * s1MapSize, c2Map + c2MapNum / 2 * c2MapSize, c2Conv + c2MapNum / 2 * c2ConvSize, c2Bias + c2MapNum / 2, params);
}
void slqAlexNet::ForwardS2()
{
int params[] = { s2MapNum, c2MapHigh, c2MapWidth, s2MapHigh, s2MapWidth, poolSpace, poolStride, 1 };
float tmp[c2UnitNum];
memcpy((char*)tmp, (char*)c2Map, sizeof(float)*c2UnitNum);
std::fill(s2Map, s2Map + s2UnitNum, 0.f);
PoolingOpt(c2Map, s2Map, s2Pool, s2Bias, params);
}
void slqAlexNet::ForwardC3()
{
int params[] = { s2MapNum, c3MapNum, s2MapHigh, s2MapWidth, c3MapHigh, c3MapWidth, c3ConvHigh, c3ConvWidth, c3ConvStride, 1 };
float tmp[s2UnitNum];
memcpy((char*)tmp, (char*)s2Map, sizeof(float)*s2UnitNum);
std::fill(c3Map, c3Map + c3UnitNum, 0.f);
ConvolutionOpt(s2Map, c3Map, c3Conv, c3Bias, params);
}
void slqAlexNet::ForwardC4()
{
int params[] = { c3MapNum / 2, c4MapNum / 2, c3MapHigh, c3MapWidth, c4MapHigh, c4MapWidth, c4ConvHigh, c4ConvWidth, c4ConvStride, 1 };
float tmp[c3UnitNum];
memcpy((char*)tmp, (char*)c3Map, sizeof(float)*c3UnitNum);
std::fill(c4Map, c4Map + c4UnitNum, 0.f);
ConvolutionOpt(c3Map, c4Map, c4Conv, c4Bias, params);
ConvolutionOpt(c3Map + c3MapNum / 2 * c3MapSize, c4Map + c4MapNum / 2 * c4MapSize, c4Conv + c4MapNum / 2 * c4ConvSize, c4Bias + c4MapNum / 2, params);
}
void slqAlexNet::ForwardC5()
{
int params[] = { c4MapNum / 2, c5MapNum / 2, c4MapHigh, c4MapWidth, c5MapHigh, c5MapWidth, c5ConvHigh, c5ConvWidth, c5ConvStride, 0 };
float tmp[c4UnitNum];
memcpy((char*)tmp, (char*)c4Map, sizeof(float)*c4UnitNum);
std::fill(c5Map, c5Map + c5UnitNum, 0.f);
ConvolutionOpt(c4Map, c5Map, c5Conv, c5Bias, params);
ConvolutionOpt(c4Map + c4MapNum / 2 * c4MapSize, c5Map + c5MapNum / 2 * c5MapSize, c5Conv + c5MapNum / 2 * c5ConvSize, c5Bias + c5MapNum / 2, params);
}
void slqAlexNet::ForwardS5()
{
int params[] = { s5MapNum, c5MapHigh, c5MapWidth, s5MapHigh, s5MapWidth, poolSpace, poolStride, 0 };
float tmp[c5UnitNum];
memcpy((char*)tmp, (char*)c5Map, sizeof(float)*c5UnitNum);
std::fill(s5Map, s5Map + s5UnitNum, 0.f);
PoolingOpt(c5Map, s5Map, s5Pool, s5Bias, params);
}
void slqAlexNet::ForwardF1()
{
int oIdx;
int iIdx;
float tmp[s5UnitNum];
memcpy((char*)tmp, (char*)s5Map, sizeof(float)*s5UnitNum);
std::fill(f1Map, f1Map + f1UnitNum, 0.f);
for (oIdx = 0; oIdx < f1UnitNum; oIdx++)
{
float *curmap = f1Map + oIdx;
for (iIdx = 0; iIdx < s5UnitNum; iIdx++)
{
if (!F1Table[iIdx][oIdx])
continue;
*curmap += s5Map[iIdx] * f1Conn[iIdx * f1UnitNum + oIdx];
}
*curmap += f1Bias[oIdx];
*curmap = ACTIVATION(*curmap);
}
}
void slqAlexNet::ForwardF2()
{
int oIdx;
int iIdx;
float tmp[f1UnitNum];
memcpy((char*)tmp, (char*)f1Map, sizeof(float)*f1UnitNum);
std::fill(f2Map, f2Map + f2UnitNum, 0.f);
for (oIdx = 0; oIdx < f2UnitNum; oIdx++)
{
float *curmap = f2Map + oIdx;
for (iIdx = 0; iIdx < f1UnitNum; iIdx++)
{
if (!F2Table[iIdx][oIdx])
continue;
*curmap += f1Map[iIdx] * f2Conn[iIdx * f2UnitNum + oIdx];
}
*curmap += f2Bias[oIdx];
*curmap = ACTIVATION(*curmap);
}
}
void slqAlexNet::ForwardF3()
{
int oIdx;
int iIdx;
float tmp[f2UnitNum];
memcpy((char*)tmp, (char*)f2Map, sizeof(float)*f2UnitNum);
std::fill(f3Map, f3Map + f3UnitNum, 0.f);
for (oIdx = 0; oIdx < f3UnitNum; oIdx++)
{
float *curmap = f3Map + oIdx;
for (iIdx = 0; iIdx < f2UnitNum; iIdx++)
{
*curmap += f2Map[iIdx] * f3Conn[iIdx * f3UnitNum + oIdx];
}
*curmap += f3Bias[oIdx];
*curmap = ACTIVATION(*curmap);
}
}
反馈运算:
void slqAlexNet::BackwardF3()
{
int oIdx;
int iIdx;
float tmpf3[f3UnitNum];
memcpy((char*)tmpf3, (char*)f3Map, sizeof(float)*f3UnitNum);
for (oIdx = 0; oIdx < f3UnitNum; oIdx++)
{
f3MapDt[oIdx] = (f3Map[oIdx] - mlabel[oIdx]) * ACTDEVICE(f3Map[oIdx]);
f3BiasDt[oIdx] = f3MapDt[oIdx];
for (iIdx = 0; iIdx < f2UnitNum; iIdx++)
{
f3ConnDt[iIdx*f3UnitNum + oIdx] = f3MapDt[oIdx] * f2Map[iIdx];
}
}
}
void slqAlexNet::BackwardF2()
{
int oIdx;
int iIdx;
for (oIdx = 0; oIdx < f2UnitNum; oIdx++)
{
float curdt = 0.f;
for (iIdx = 0; iIdx < f3UnitNum; iIdx++)
{
curdt += f3MapDt[iIdx] * f3Conn[oIdx * f3UnitNum + iIdx];
}
f2MapDt[oIdx] = ACTDEVICE(f2Map[oIdx]) * curdt;
f2BiasDt[oIdx] = f2MapDt[oIdx];
for (iIdx = 0; iIdx < f1UnitNum; iIdx++)
{
if (!F2Table[iIdx][oIdx])
continue;
f2ConnDt[iIdx * f2UnitNum + oIdx] = f2MapDt[oIdx] * f1Map[iIdx];
}
}
}
void slqAlexNet::BackwardF1()
{
int oIdx;
int iIdx;
for (oIdx = 0; oIdx < f1UnitNum; oIdx++)
{
float curdt = 0.f;
for (iIdx = 0; iIdx < f2UnitNum; iIdx++)
{
if (!F2Table[oIdx][iIdx])
continue;
curdt += f2MapDt[iIdx] * f2Conn[oIdx * f2UnitNum + iIdx];
}
f1MapDt[oIdx] = ACTDEVICE(f1Map[oIdx]) * curdt;
f1BiasDt[oIdx] = f1MapDt[oIdx];
for (iIdx = 0; iIdx < s5UnitNum; iIdx++)
{
if (!F1Table[iIdx][oIdx])
continue;
f1ConnDt[iIdx * f1UnitNum + oIdx] = f1MapDt[oIdx] * s5Map[iIdx];
}
}
}
void slqAlexNet::BackwardS5()
{
int iIdx;
int iod;
int odeepIdx;
int ohIdx;
int owIdx;
int phIdx;
int pwIdx;
std::fill(s5BiasDt, s5BiasDt + s5MapNum, 0.f);
std::fill(s5PoolDt, s5PoolDt + s5MapNum, 0.f);
for (odeepIdx = 0; odeepIdx < s5MapNum; odeepIdx++)
{
for (ohIdx = 0; ohIdx < s5MapHigh; ohIdx++)
{
iod = odeepIdx*s5MapSize + ohIdx * s5MapWidth;
for (owIdx = 0; owIdx < s5MapWidth; owIdx++)
{
float curdt = 0.f;
for (iIdx = 0; iIdx < f1UnitNum; iIdx++)
{
if (!F1Table[iod + owIdx][iIdx])
continue;
curdt += f1MapDt[iIdx] * f1Conn[(iod + owIdx)*f1UnitNum + iIdx];
}
s5MapDt[iod + owIdx] = ACTDEVICE(s5Map[iod + owIdx]) * curdt;
s5BiasDt[odeepIdx] += s5MapDt[iod + owIdx];
float *curin = c5Map + odeepIdx * c5MapSize + ohIdx * poolStride * c5MapWidth + owIdx * poolStride;
curdt = FLT_MIN;
for (phIdx = 0; phIdx < poolSpace; phIdx++)
{
for (pwIdx = 0; pwIdx < poolSpace; pwIdx++)
{
curdt = curdt > (*(curin + phIdx * c5MapWidth + pwIdx)) ? curdt : (*(curin + phIdx * c5MapWidth + pwIdx));
}
}
s5PoolDt[odeepIdx] += curdt * s5MapDt[iod + owIdx];
}
}
}
}
void slqAlexNet::BackwardC5()
{
int odeepIdx;
int ideepIdx;
int ohIdx;
int owIdx;
int phIdx;
int pwIdx;
int iod;
int vod;
int svh;
std::fill(c5MapDt, c5MapDt + c5UnitNum, 0.f);
std::fill(c5BiasDt, c5BiasDt + c5MapNum, 0.f);
std::fill(c5ConvDt, c5ConvDt + c5ConvUNum, 0.f);
for (odeepIdx = 0; odeepIdx < c5MapNum; odeepIdx++)
{
for (ohIdx = 0; ohIdx < s5MapHigh; ohIdx++)
{
for (owIdx = 0; owIdx < s5MapWidth; owIdx++)
{
iod = odeepIdx * c5MapSize + ohIdx * poolStride * c5MapWidth + owIdx * poolStride;
vod = odeepIdx * s5MapSize + ohIdx * s5MapWidth + owIdx;
float curmax = FLT_MIN;
int hmax = 0;
int wmax = 0;
for (phIdx = 0; phIdx < poolSpace; phIdx++)
{
for (pwIdx = 0; pwIdx < poolSpace; pwIdx++)
{
hmax = curmax > c5Map[iod + phIdx * c5MapWidth + pwIdx] ? hmax : phIdx;
wmax = curmax > c5Map[iod + phIdx * c5MapWidth + pwIdx] ? wmax : pwIdx;
curmax = curmax > c5Map[iod + phIdx * c5MapWidth + pwIdx] ? curmax : c5Map[iod + phIdx * c5MapWidth + pwIdx];
}
}
c5MapDt[iod + hmax * c5MapWidth + wmax] += ACTDEVICE(c5Map[iod + hmax * c5MapWidth + wmax]) * s5Pool[odeepIdx] * s5MapDt[vod];
for (phIdx = 0; phIdx < poolSpace; phIdx++)
{
for (pwIdx = 0; pwIdx < poolSpace; pwIdx++)
{
c5BiasDt[odeepIdx] += c5MapDt[iod + phIdx * c5MapWidth + pwIdx];
}
}
}
}
}
for (odeepIdx = 0; odeepIdx < c5MapNum / 2; odeepIdx++)
{
for (ideepIdx = 0; ideepIdx < c5ConvDeep; ideepIdx++)
{
for (phIdx = 0; phIdx < c5ConvHigh; phIdx++)
{
for (pwIdx = 0; pwIdx < c5ConvWidth; pwIdx++)
{
iod = odeepIdx * c5ConvSize + ideepIdx * c5ConvTensor + phIdx * c5ConvWidth + pwIdx;
float *curconv = c5ConvDt + iod;
for (ohIdx = 0; ohIdx < c5MapHigh; ohIdx++)
{
for (owIdx = 0; owIdx < c5MapWidth; owIdx++)
{
svh = ideepIdx * c4MapSize + (phIdx + ohIdx * c5ConvStride)*c4MapWidth + (pwIdx + owIdx * c5ConvStride);
vod = odeepIdx * c5MapSize + ohIdx * c5MapWidth + owIdx;
*curconv += c4Map[svh] * c5MapDt[vod];
}
}
}
}
}
}
for (odeepIdx = c5MapNum / 2; odeepIdx < c5MapNum; odeepIdx++)
{
for (ideepIdx = c5ConvDeep; ideepIdx < c4MapNum; ideepIdx++)
{
for (phIdx = 0; phIdx < c5ConvHigh; phIdx++)
{
for (pwIdx = 0; pwIdx < c5ConvWidth; pwIdx++)
{
iod = odeepIdx * c5ConvSize + (ideepIdx - c5ConvDeep) * c5ConvTensor + phIdx * c5ConvWidth + pwIdx;
float *curconv = c5ConvDt + iod;
for (ohIdx = 0; ohIdx < c5MapHigh; ohIdx++)
{
for (owIdx = 0; owIdx < c5MapWidth; owIdx++)
{
svh = ideepIdx * c4MapSize + (phIdx + ohIdx * c5ConvStride)*c4MapWidth + (pwIdx + owIdx * c5ConvStride);
vod = odeepIdx * c5MapSize + ohIdx * c5MapWidth + owIdx;
*curconv += c4Map[svh] * c5MapDt[vod];
}
}
}
}
}
}
}
void slqAlexNet::BackwardC4()
{
int odeepIdx;
int ideepIdx;
int ohIdx;
int owIdx;
int phIdx;
int pwIdx;
int iod;
int vod;
int svh;
std::fill(c4MapDt, c4MapDt + c4UnitNum, 0.f);
std::fill(c4BiasDt, c4BiasDt + c4MapNum, 0.f);
std::fill(c4ConvDt, c4ConvDt + c4ConvUNum, 0.f);
for (odeepIdx = 0; odeepIdx < c4MapNum / 2; odeepIdx++)
{
for (ideepIdx = 0; ideepIdx < c5MapNum / 2; ideepIdx++)
{
for (phIdx = 0; phIdx < c5ConvHigh; phIdx++)
{
for (pwIdx = 0; pwIdx < c5ConvWidth; pwIdx++)
{
svh = ideepIdx * c5ConvSize + odeepIdx * c5ConvTensor + phIdx * c5ConvWidth + pwIdx;
for (ohIdx = 0; ohIdx < c5MapHigh; ohIdx++)
{
for (owIdx = 0; owIdx < c5MapWidth; owIdx++)
{
iod = odeepIdx * c4MapSize + (phIdx + ohIdx * c5ConvStride) * c4MapWidth + (pwIdx + owIdx * c5ConvStride);
vod = ideepIdx * c5MapSize + ohIdx * c5MapWidth + owIdx;
c4MapDt[iod] += ACTDEVICE(c4Map[iod]) * c5Conv[svh] * c5MapDt[vod];
}
}
}
}
}
}
for (odeepIdx = c4MapNum / 2; odeepIdx < c4MapNum; odeepIdx++)
{
for (ideepIdx = c5MapNum / 2; ideepIdx < c5MapNum; ideepIdx++)
{
for (phIdx = 0; phIdx < c5ConvHigh; phIdx++)
{
for (pwIdx = 0; pwIdx < c5ConvWidth; pwIdx++)
{
svh = ideepIdx * c5ConvSize + (odeepIdx - c5ConvDeep) * c5ConvTensor + phIdx * c5ConvWidth + pwIdx;
for (ohIdx = 0; ohIdx < c5MapHigh; ohIdx++)
{
for (owIdx = 0; owIdx < c5MapWidth; owIdx++)
{
iod = odeepIdx * c4MapSize + (phIdx + ohIdx * c5ConvStride) * c4MapWidth + (pwIdx + owIdx * c5ConvStride);
vod = ideepIdx * c5MapSize + ohIdx * c5MapWidth + owIdx;
c4MapDt[iod] += ACTDEVICE(c4Map[iod]) * c5Conv[svh] * c5MapDt[vod];
}
}
}
}
}
}
for (odeepIdx = 0; odeepIdx < c4MapNum / 2; odeepIdx++)
{
for (ideepIdx = 0; ideepIdx < c4ConvDeep; ideepIdx++)
{
for (phIdx = 0; phIdx < c4ConvHigh; phIdx++)
{
for (pwIdx = 0; pwIdx < c4ConvWidth; pwIdx++)
{
iod = odeepIdx * c4ConvSize + ideepIdx * c4ConvTensor + phIdx * c4ConvWidth + pwIdx;
for (ohIdx = 1; ohIdx < c4MapHigh - 1; ohIdx++)
{
for (owIdx = 1; owIdx < c4MapWidth - 1; owIdx++)
{
vod = odeepIdx * c4MapSize + ohIdx * c4MapWidth + owIdx;
svh = ideepIdx * c3MapSize + ((ohIdx - 1) * c4ConvStride + phIdx) * c3MapWidth + ((owIdx - 1) * c4ConvStride + pwIdx);
c4BiasDt[odeepIdx] += c4MapDt[vod];
c4ConvDt[iod] += c3Map[svh] * c4MapDt[vod];
}
}
}
}
}
}
for (odeepIdx = c4MapNum / 2; odeepIdx < c4MapNum; odeepIdx++)
{
for (ideepIdx = c4ConvDeep; ideepIdx < c3MapNum; ideepIdx++)
{
for (phIdx = 0; phIdx < c4ConvHigh; phIdx++)
{
for (pwIdx = 0; pwIdx < c4ConvWidth; pwIdx++)
{
iod = odeepIdx * c4ConvSize + (ideepIdx - c4ConvDeep) * c4ConvTensor + phIdx * c4ConvWidth + pwIdx;
for (ohIdx = 1; ohIdx < c4MapHigh - 1; ohIdx++)
{
for (owIdx = 1; owIdx < c4MapWidth - 1; owIdx++)
{
vod = odeepIdx * c4MapSize + ohIdx * c4MapWidth + owIdx;
svh = ideepIdx * c3MapSize + ((ohIdx - 1) * c4ConvStride + phIdx) * c3MapWidth + ((owIdx - 1) * c4ConvStride + pwIdx);
c4BiasDt[odeepIdx] += c4MapDt[vod];
c4ConvDt[iod] += c3Map[svh] * c4MapDt[vod];
}
}
}
}
}
}
}
void slqAlexNet::BackwardC3()
{
int odeepIdx;
int ideepIdx;
int ohIdx;
int owIdx;
int phIdx;
int pwIdx;
int iod;
int vod;
int svh;
std::fill(c3MapDt, c3MapDt + c3UnitNum, 0.f);
std::fill(c3BiasDt, c3BiasDt + c3MapNum, 0.f);
std::fill(c3ConvDt, c3ConvDt + c3ConvUNum, 0.f);
for (odeepIdx = 0; odeepIdx < c3MapNum / 2; odeepIdx++)
{
for (ideepIdx = 0; ideepIdx < c4MapNum / 2; ideepIdx++)
{
for (phIdx = 0; phIdx < c4ConvHigh; phIdx++)
{
for (pwIdx = 0; pwIdx < c4ConvWidth; pwIdx++)
{
svh = ideepIdx * c4ConvSize + odeepIdx * c4ConvTensor + phIdx * c4ConvWidth + pwIdx;
for (ohIdx = 1; ohIdx < c4MapHigh - 1; ohIdx++)
{
for (owIdx = 1; owIdx < c4MapWidth - 1; owIdx++)
{
iod = odeepIdx * c3MapSize + (phIdx + (ohIdx - 1) * c4ConvStride) * c3MapWidth + (pwIdx + (owIdx - 1) * c4ConvStride);
vod = ideepIdx * c4MapSize + ohIdx * c4MapWidth + owIdx;
c3MapDt[iod] += ACTDEVICE(c3Map[iod]) * c4Conv[svh] * c4MapDt[vod];
}
}
}
}
}
}
for (odeepIdx = c3MapNum / 2; odeepIdx < c3MapNum; odeepIdx++)
{
for (ideepIdx = c4MapNum / 2; ideepIdx < c4MapNum; ideepIdx++)
{
for (phIdx = 0; phIdx < c4ConvHigh; phIdx++)
{
for (pwIdx = 0; pwIdx < c4ConvWidth; pwIdx++)
{
svh = ideepIdx * c4ConvSize + (odeepIdx - c4ConvDeep) * c4ConvTensor + phIdx * c4ConvWidth + pwIdx;
for (ohIdx = 1; ohIdx < c4MapHigh - 1; ohIdx++)
{
for (owIdx = 1; owIdx < c4MapWidth - 1; owIdx++)
{
iod = odeepIdx * c3MapSize + (phIdx + (ohIdx - 1) * c4ConvStride) * c3MapWidth + (pwIdx + (owIdx - 1) * c4ConvStride);
vod = ideepIdx * c4MapSize + ohIdx * c4MapWidth + owIdx;
c3MapDt[iod] += ACTDEVICE(c3Map[iod]) * c4Conv[svh] * c4MapDt[vod];
}
}
}
}
}
}
for (odeepIdx = 0; odeepIdx < c3MapNum; odeepIdx++)
{
for (ideepIdx = 0; ideepIdx < c3ConvDeep; ideepIdx++)
{
if (!CONV3Table[odeepIdx][ideepIdx])
continue;
for (phIdx = 0; phIdx < c3ConvHigh; phIdx++)
{
for (pwIdx = 0; pwIdx < c3ConvWidth; pwIdx++)
{
iod = odeepIdx * c3ConvSize + ideepIdx * c3ConvTensor + phIdx * c3ConvWidth + pwIdx;
for (ohIdx = 1; ohIdx < c3MapHigh - 1; ohIdx++)
{
for (owIdx = 1; owIdx < c3MapWidth - 1; owIdx++)
{
vod = odeepIdx * c3MapSize + ohIdx * c3MapWidth + owIdx;
svh = ideepIdx * s2MapSize + ((ohIdx - 1) * c3ConvStride + phIdx) * s2MapWidth + ((owIdx - 1) * c3ConvStride + pwIdx);
c3BiasDt[odeepIdx] += c3MapDt[vod];
c3ConvDt[iod] += c3MapDt[vod] * s2Map[svh];
}
}
}
}
}
}
}
void slqAlexNet::BackwardS2()
{
int odeepIdx;
int ideepIdx;
int ohIdx;
int owIdx;
int phIdx;
int pwIdx;
int iod;
int vod;
int svh;
std::fill(s2MapDt, s2MapDt + s2UnitNum, 0.f);
std::fill(s2BiasDt, s2BiasDt + s2MapNum, 0.f);
std::fill(s2PoolDt, s2PoolDt + s2MapNum, 0.f);
for (odeepIdx = 0; odeepIdx < s2MapNum; odeepIdx++)
{
for (ideepIdx = 0; ideepIdx < c3MapNum; ideepIdx++)
{
if (!CONV3Table[ideepIdx][odeepIdx])
continue;
for (phIdx = 0; phIdx < c3ConvHigh; phIdx++)
{
for (pwIdx = 0; pwIdx < c3ConvWidth; pwIdx++)
{
svh = ideepIdx * c3ConvSize + odeepIdx * c3ConvTensor + phIdx * c3ConvWidth + pwIdx;
for (ohIdx = 1; ohIdx < c3MapHigh - 1; ohIdx++)
{
for (owIdx = 1; owIdx < c3MapWidth - 1; owIdx++)
{
iod = odeepIdx * s2MapSize + (phIdx + (ohIdx - 1) * c3ConvStride) * s2MapWidth + (pwIdx + (owIdx - 1) * c3ConvStride);
vod = ideepIdx * c3MapSize + ohIdx * c3MapWidth + owIdx;
s2MapDt[iod] += ACTDEVICE(s2Map[iod]) * c3Conv[svh] * c3MapDt[vod];
}
}
}
}
}
}
for (odeepIdx = 0; odeepIdx < s2MapNum; odeepIdx++)
{
for (ohIdx = 1; ohIdx < s2MapHigh - 1; ohIdx++)
{
iod = odeepIdx*s2MapSize + ohIdx * s2MapWidth;
for (owIdx = 1; owIdx < s2MapWidth - 1; owIdx++)
{
float *curin = c2Map + odeepIdx * c2MapSize + (ohIdx - 1) * poolStride * c2MapWidth + (owIdx - 1) * poolStride;
float curdt = FLT_MIN;
for (phIdx = 0; phIdx < poolSpace; phIdx++)
{
for (pwIdx = 0; pwIdx < poolSpace; pwIdx++)
{
curdt = curdt >(*(curin + phIdx * c2MapWidth + pwIdx)) ? curdt : (*(curin + phIdx * c2MapWidth + pwIdx));
}
}
s2BiasDt[odeepIdx] += s2MapDt[iod + owIdx];
s2PoolDt[odeepIdx] += curdt * s2MapDt[iod + owIdx];
}
}
}
}
void slqAlexNet::BackwardC2()
{
int odeepIdx;
int ideepIdx;
int ohIdx;
int owIdx;
int phIdx;
int pwIdx;
int iod;
int vod;
int svh;
std::fill(c2MapDt, c2MapDt + c2UnitNum, 0.f);
std::fill(c2BiasDt, c2BiasDt + c2MapNum, 0.f);
std::fill(c2ConvDt, c2ConvDt + c2ConvUNum, 0.f);
for (odeepIdx = 0; odeepIdx < c2MapNum; odeepIdx++)
{
for (ohIdx = 1; ohIdx < s2MapHigh - 1; ohIdx++)
{
for (owIdx = 1; owIdx < s2MapWidth - 1; owIdx++)
{
iod = odeepIdx * c2MapSize + (ohIdx - 1) * poolStride * c2MapWidth + (owIdx - 1) * poolStride;
vod = odeepIdx * s2MapSize + ohIdx * s2MapWidth + owIdx;
float curmax = FLT_MIN;
int hmax = 0;
int wmax = 0;
for (phIdx = 0; phIdx < poolSpace; phIdx++)
{
for (pwIdx = 0; pwIdx < poolSpace; pwIdx++)
{
hmax = curmax > c2Map[iod + phIdx * c2MapWidth + pwIdx] ? hmax : phIdx;
wmax = curmax > c2Map[iod + phIdx * c2MapWidth + pwIdx] ? wmax : pwIdx;
curmax = curmax > c2Map[iod + phIdx * c2MapWidth + pwIdx] ? curmax : c2Map[iod + phIdx * c2MapWidth + pwIdx];
}
}
c2MapDt[iod + hmax * c2MapWidth + wmax] += ACTDEVICE(c2Map[iod + phIdx * c2MapWidth + pwIdx]) * s2Pool[odeepIdx] * s2MapDt[vod];
for (phIdx = 0; phIdx < poolSpace; phIdx++)
{
for (pwIdx = 0; pwIdx < poolSpace; pwIdx++)
{
c2BiasDt[odeepIdx] += c2MapDt[iod + phIdx * c2MapWidth + pwIdx];
}
}
}
}
}
for (odeepIdx = 0; odeepIdx < c2MapNum / 2; odeepIdx++)
{
for (ideepIdx = 0; ideepIdx < c2ConvDeep; ideepIdx++)
{
for (phIdx = 0; phIdx < c2ConvHigh; phIdx++)
{
for (pwIdx = 0; pwIdx < c2ConvWidth; pwIdx++)
{
iod = odeepIdx * c2ConvSize + ideepIdx * c2ConvTensor + phIdx * c2ConvWidth + pwIdx;
for (ohIdx = 0; ohIdx < c2MapHigh; ohIdx++)
{
for (owIdx = 0; owIdx < c2MapWidth; owIdx++)
{
vod = odeepIdx * c2MapSize + ohIdx * c2MapWidth + owIdx;
svh = ideepIdx * s1MapSize + (ohIdx * c2ConvStride + phIdx) * s1MapWidth + (owIdx * c2ConvStride + pwIdx);
c2ConvDt[iod] += c2MapDt[vod] * s1Map[svh];
}
}
}
}
}
}
for (odeepIdx = c2MapNum / 2; odeepIdx < c2MapNum; odeepIdx++)
{
for (ideepIdx = c2ConvDeep; ideepIdx < s1MapNum; ideepIdx++)
{
for (phIdx = 0; phIdx < c2ConvHigh; phIdx++)
{
for (pwIdx = 0; pwIdx < c2ConvWidth; pwIdx++)
{
iod = odeepIdx * c2ConvSize + (ideepIdx - c2ConvDeep) * c2ConvTensor + phIdx * c2ConvWidth + pwIdx;
for (ohIdx = 0; ohIdx < c2MapHigh; ohIdx++)
{
for (owIdx = 0; owIdx < c2MapWidth; owIdx++)
{
vod = odeepIdx * c2MapSize + ohIdx * c2MapWidth + owIdx;
svh = ideepIdx * s1MapSize + (ohIdx * c2ConvStride + phIdx) * s1MapWidth + (owIdx * c2ConvStride + pwIdx);
c2ConvDt[iod] += c2MapDt[vod] * s1Map[svh];
}
}
}
}
}
}
}
void slqAlexNet::BackwardS1()
{
int odeepIdx;
int ideepIdx;
int ohIdx;
int owIdx;
int phIdx;
int pwIdx;
int iod;
int vod;
int svh;
std::fill(s1MapDt, s1MapDt + s1UnitNum, 0.f);
std::fill(s1BiasDt, s1BiasDt + s1MapNum, 0.f);
std::fill(s1PoolDt, s1PoolDt + s1MapNum, 0.f);
for (odeepIdx = 0; odeepIdx < s1MapNum / 2; odeepIdx++)
{
for (ideepIdx = 0; ideepIdx < c2ConvDeep; ideepIdx++)
{
for (phIdx = 0; phIdx < c2ConvHigh; phIdx++)
{
for (pwIdx = 0; pwIdx < c2ConvWidth; pwIdx++)
{
vod = odeepIdx * c2ConvSize + ideepIdx * c2ConvTensor + phIdx * c2ConvHigh + pwIdx;
for (ohIdx = 0; ohIdx < c2MapHigh; ohIdx++)
{
for (owIdx = 0; owIdx < c2MapWidth; owIdx++)
{
iod = odeepIdx * s1MapSize + (ohIdx * c2ConvStride + phIdx) * s1MapWidth + (owIdx * c2ConvStride + pwIdx);
svh = ideepIdx * c2MapSize + ohIdx * c2MapWidth + owIdx;
s1MapDt[iod] += ACTDEVICE(s1Map[iod]) * c2Conv[vod] * c2MapDt[svh];
}
}
}
}
}
}
for (odeepIdx = s1MapNum / 2; odeepIdx < s1MapNum; odeepIdx++)
{
for (ideepIdx = 0; ideepIdx < c2ConvDeep; ideepIdx++)
{
for (phIdx = 0; phIdx < c2ConvHigh; phIdx++)
{
for (pwIdx = 0; pwIdx < c2ConvWidth; pwIdx++)
{
vod = odeepIdx * c2ConvSize + ideepIdx * c2ConvTensor + phIdx * c2ConvHigh + pwIdx;
for (ohIdx = 0; ohIdx < c2MapHigh; ohIdx++)
{
for (owIdx = 0; owIdx < c2MapWidth; owIdx++)
{
iod = odeepIdx * s1MapSize + (ohIdx * c2ConvStride + phIdx) * s1MapWidth + (owIdx * c2ConvStride + pwIdx);
svh = (ideepIdx + c2ConvDeep) * c2MapSize + ohIdx * c2MapWidth + owIdx;
s1MapDt[iod] += ACTDEVICE(s1Map[iod]) * c2Conv[vod] * c2MapDt[svh];
}
}
}
}
}
}
for (odeepIdx = 0; odeepIdx < s1MapNum; odeepIdx++)
{
for (ohIdx = 2; ohIdx < s1MapHigh - 2; ohIdx++)
{
iod = odeepIdx*s1MapSize + ohIdx * s1MapWidth;
for (owIdx = 2; owIdx < s1MapWidth - 2; owIdx++)
{
float *curin = c1Map + odeepIdx * c1MapSize + (ohIdx - 2) * poolStride * c1MapWidth + (owIdx - 2) * poolStride;
float curdt = FLT_MIN;
for (phIdx = 0; phIdx < poolSpace; phIdx++)
{
for (pwIdx = 0; pwIdx < poolSpace; pwIdx++)
{
curdt = curdt > (*(curin + phIdx * c1MapWidth + pwIdx)) ? curdt : (*(curin + phIdx * c1MapWidth + pwIdx));
}
}
s1BiasDt[odeepIdx] += s1MapDt[iod + owIdx];
s1PoolDt[odeepIdx] += curdt * s1MapDt[iod + owIdx];
}
}
}
}
void slqAlexNet::BackwardC1()
{
int odeepIdx;
int ideepIdx;
int ohIdx;
int owIdx;
int phIdx;
int pwIdx;
int iod;
int vod;
int svh;
std::fill(c1MapDt, c1MapDt + c1UnitNum, 0.f);
std::fill(c1BiasDt, c1BiasDt + c1MapNum, 0.f);
std::fill(c1ConvDt, c1ConvDt + c1ConvUNum, 0.f);
for (odeepIdx = 0; odeepIdx < c1MapNum; odeepIdx++)
{
for (ohIdx = 2; ohIdx < s1MapHigh - 2; ohIdx++)
{
for (owIdx = 2; owIdx < s1MapWidth - 2; owIdx++)
{
iod = odeepIdx * c1MapSize + (ohIdx - 2) * poolStride * c1MapWidth + (owIdx - 2) * poolStride;
vod = odeepIdx * s1MapSize + ohIdx * s1MapWidth + owIdx;
float curmax = FLT_MIN;
int hmax = 0;
int wmax = 0;
for (phIdx = 0; phIdx < poolSpace; phIdx++)
{
for (pwIdx = 0; pwIdx < poolSpace; pwIdx++)
{
hmax = curmax > c1Map[iod + phIdx * c1MapWidth + pwIdx] ? hmax : phIdx;
wmax = curmax > c1Map[iod + phIdx * c1MapWidth + pwIdx] ? wmax : pwIdx;
curmax = curmax > c1Map[iod + phIdx * c1MapWidth + pwIdx] ? curmax : c1Map[iod + phIdx * c1MapWidth + pwIdx];
}
}
c1MapDt[iod + hmax * c1MapWidth + wmax] += ACTDEVICE(c1Map[iod + hmax * c1MapWidth + wmax]) * s1Pool[odeepIdx] * s1MapDt[vod];
for (phIdx = 0; phIdx < poolSpace; phIdx++)
{
for (pwIdx = 0; pwIdx < poolSpace; pwIdx++)
{
c1BiasDt[odeepIdx] += c1MapDt[iod + phIdx * c1MapWidth + pwIdx];
}
}
}
}
for (ideepIdx = 0; ideepIdx < c1ConvDeep; ideepIdx++)
{
for (phIdx = 0; phIdx < c1ConvHigh; phIdx++)
{
for (pwIdx = 0; pwIdx < c1ConvWidth; pwIdx++)
{
vod = odeepIdx * c1ConvSize + ideepIdx * c1ConvTensor + phIdx * c1ConvWidth + pwIdx;
for (ohIdx = 0; ohIdx < c1MapHigh; ohIdx++)
{
for (owIdx = 0; owIdx < c1MapWidth; owIdx++)
{
iod = ideepIdx * inMapSize + (phIdx + ohIdx * c1ConvStride) * inMapWidth + (pwIdx + owIdx * c1ConvStride);
svh = odeepIdx * c1MapSize + ohIdx * c1MapWidth + owIdx;
c1ConvDt[vod] += inMap[iod] * c1MapDt[svh];
}
}
}
}
}
}
}
版权声明:本文为aitazhixin原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。