Orz_TanLaLa 2022-07-19 12:23 采纳率: 66.7%
浏览 13
已结题

我的线性分类器哪里有问题

本人在学习计算机视觉,正在学习线性分类器,尝试自己实现一个

一些信息:
  • 参数:矢量的数组w,标量的数组b
  • R=L2正则项=w0各项平方和到w9各项平方和之和
  • 更新参数使用梯度下降算法
  • 数据集:cifar-10
  • 图像表示:直接将数据转化为矢量xi
  • yi=xi对应的类型=0到9中的数
  • Li=多类支撑向量机损失=max(0,s(i,j)-s(i,yi)+1)
  • N数据数量
  • 损失L=L0到LN之和+lambda*R
  • 线性分类器:sij=wj点乘xi+bj
由于我没深入学习过线性代数和微积分,所以我想确认的是梯度下降算法是不是这样的:

由于Li=求和 i=0到N max(0,s(i,j)-s(i,yi)+1)
其中当s(i,j)-s(i,yi)+1>0时,max(0,s(i,j)-s(i,yi)+1)导数为
[xi
1
-xi
-1]
所以Li导数只需将这些全判断一次是否大于0,加起来即可
为此,我写了一些千篇一律的函数,其中define D 3072

void add(float a[D], unsigned char b[D]) {
    int i;
    for (i = 0; i < D; i++) {
        a[i] += b[i];
    }
}
void add(float a[D], float b[D]) {
    int i;
    for (i = 0; i < D; i++) {
        a[i] += b[i];
    }
}
void sub(float a[D], unsigned char b[D]) {
    int i;
    for (i = 0; i < D; i++) {
        a[i] -= b[i];
    }
}
void sub(float a[D], float b[D]) {
    int i;
    for (i = 0; i < D; i++) {
        a[i] -= b[i];
    }
}
void div(float a[D], float b) {
    int i;
    for (i = 0; i < D; i++) {
        a[i] /= b;
    }
}
void mul(float a[D], float b) {
    int i;
    for (i = 0; i < D; i++) {
        a[i] *= b;
    }
}

创建了一些用于计算导数的变量,其中define C 10

float wL[C][D] = {};
float bL[C] = {};
float wR[C][D] = {};

在计算损失的同时计算导数

float R() {
    int i, j;
    float r = 0.0f;
    memset(wR, 0, sizeof(wR));
    for (i = 0; i < C; i++) {
        for (j = 0; j < D; j++) {
            r += w[i][j] * w[i][j];
            wR[i][j] = w[i][j] * 2 * LA;
        }
    }
    return r;
}
float L() {
    int i, j;
    float r = 0.0f;
    float t = 0.0f;
    memset(wL, 0, sizeof(wL));
    memset(bL, 0, sizeof(bL));
    for (i = 0; i < 50000; i++) {
        for (j = 0; j < C; j++) {
            if (j == x[i].c) continue;
            t = s(i, j) - s(i, x[i].c) + 1;
            if (t > 0) {
                r += t;
                add(wL[j], x[i].x);
                bL[j] += 1;
                sub(wL[x[i].c], x[i].x);
                bL[x[i].c] -= 1;
            }
        }
    }
    for (i = 0; i < C; i++) {
        div(wL[i], 50000);
        bL[i] /= 50000;
        add(wL[i], wR[i]);
    }
    r /= 50000;
    return r + R() * LA;
}

最后更新参数(在main函数中),其中LR是学习率

float L1, L2 = 0.0f;
    L1 = L();
    for (i = 0; i < C; i++) {
        mul(wL[i], LR);
        sub(w[i], wL[i]);
    }
    L2 = L();
    while (abs(L2 - L1) > 0000000.1) {
        L1 = L2;
        for (i = 0; i < C; i++) {
            mul(wL[i], LR);
            sub(w[i], wL[i]);
        }
        L2 = L();
    }

结果,L几乎总是在10以下,而测试的正确率只有1000/10000(这几乎可以算运气了吧)
所以我哪里做错了
  • 写回答

0条回答 默认 最新

    报告相同问题?

    问题事件

    • 系统已结题 7月27日
    • 创建了问题 7月19日

    悬赏问题

    • ¥15 SPSS分类模型实训题步骤
    • ¥15 求解决扩散模型代码问题
    • ¥15 工创大赛太阳能电动车项目零基础要学什么
    • ¥20 limma多组间分析最终p值只有一个
    • ¥15 nopCommerce开发问题
    • ¥15 torch.multiprocessing.spawn.ProcessExitedException: process 1 terminated with signal SIGKILL
    • ¥15 QuartusⅡ15.0编译项目后,output_files中的.jdi、.sld、.sof不更新怎么解决
    • ¥15 pycharm输出和导师的一样,但是标红
    • ¥15 想问问富文本拿到的html怎么转成docx的
    • ¥15 我看了您的文章,遇到了个问题。