错误使用 sparse 指向矩阵的索引必须为正数。

错误使用 sparse指向矩阵的索引必须为正数。这个应该怎么改function [cost,thetagrad,P] = softmax_cost_grad(X,label,lambda,theta)% 用于计算代价函数值及其梯度% X:m*p输入矩阵,m为案例个数,p为加上常数项之后的属性个数 % label:m*1标签向量(数值型)% lambda:权重衰减参数weight decay parameter% theta:p*k系数矩阵,k为标签类别数 % cost:总代价函数值% thetagrad:梯度矩阵% P:m*k分类概率矩阵,p(i,j)表示第i个样本被判别为第j类的概率m = size(X,1);% 将每个标签扩展为一个k维横向量(k为标签类别数),若样本i属于第j类,则% label_extend(i,j) = 1,否则label_extend(i,j) = 0.label_extend = full(sparse(label,1:length(label),1));% 计算预测概率矩阵P = zeros(m,size(label_extend,2));for smp = 1:mP(smp,:) = exp(X(smp,:)*theta)⼀sum(exp(X(smp,:)*theta));end%计算代价函数值cost = -1 ⼀ m * [label_extend(:)]✀ * log(P(:)) + lambda ⼀ 2 * sum(theta(:).^2);%计算梯度thetagrad = -1 ⼀ m * X✀ * (label_extend - P) + lambda * theta;哥们儿 你帮我看看怎么改
2026年09月26日 09:28
有1个网友回答
网友(1):

是的sparse本身不支持单精度
你可以转化为double再用sparse
如果还要用single类型进一步节省空间
还是有办法的

实际上sparse稀疏矩阵,能够节省存储空间的原因是
避免存储矩阵中大量的0元素
而sparse实际上是寻找矩阵的非零元素,记录它们的下标值和数值

如果是single的矩阵,使用不了sparse,我们可以用find得到类似的结果
假如原来的矩阵是a,a中有很多0元素,我们想压缩存储,首先利用
[r c v]=find(a)
就可以得到每个非零元素的行下标r,列下标c ,数值v

例如:
a=[ 0 1 0 ; 0 0 2];
如果我们用sparse存成稀疏矩阵,那么
>> sparse(a)
ans =
(1,2) 1
(2,3) 2

如果我们用find函数求得非零元素的下标和值
>> [r c v]=find(a);
>> [r c v]
ans =
1 2 1
2 3 2
可见sparse矩阵的显示结果中第n行的数据 实际上就是 (r(n),c(n)) v(n)

但是要存储行列两个坐标,还是数据太多,我们只需要
[r c v]=find(a(:))
这时候数据就会以先行后列的顺序排成一个一维的数组
我们只要一个坐标r就可以记录其元素所在的位置
以上面的例子为例
>> [r c v]=find(a(:));
>> [r v]
ans =
3 1
6 2
原来(1,2)位置的元素相当于第3个,(2,3) 位置的元素相当于第6个
这时候c全部是1,不需要记录,我们只需要记录r和v就可以了
这样又可以节省一半的存储下标的空间

这个时候v的数据类型是根据原来a的数据类型来定的
如果原来的a是single型的,v就是single型的

但是r是double型的占8位,也是比较占空间的,但是下标一定是正整数
我们可以使用uint8,uint16,uint32,uint64来转换为无符号整数
根据你矩阵的大小可以选择不同位数的整数类型储存下标
uint8只占1个字节但是最多只能到255,显然不能够满足要求

uint16占2个字节大表示整数65535,

uint32占4个字节最大表示整数4,294,967,295,
可以表示6万多行x6万多列的矩阵,应该能满足要求吧

最后如果你有一个很大的single矩阵a,只有少量非零元素,想压缩储存
那么

[m n]=size(a);
[r c v]=find(a(:));
r=unit32(r);

你只需要储存 m n r v 这四个量就可以储存矩阵a的全部信息
其中m n是double型,无论矩阵多大,就两个数占16字节
而r是uint32,v是single,元素个数由矩阵中非零元素的个数决定

假如原来a矩阵大小为mxn,其中有num个非零元素
全部存取矩阵需要 m*n*4个字节的空间
而用上述办法需要 num*8+16个字节的空间
可见当非零个数达到总元素个数的一半或以上时,
存储空间非但没有减少还会增加,所以非零元素所占的比例决定了储存效率

对于sparse生成的系数矩阵,我们可以用full得到完整的矩阵
而我们用上述办法得到的 m n r v,想恢复为完整的矩阵也不会太复杂
b=zeros(m,n,class(v));
b(r)=v;
这样就可以恢复矩阵b,矩阵b和矩阵a应该是一样的
它是一种使用命令集合的形式表示的过程式编程语言,这些命令集合需要像批处理文件一样顺序执行。