for (int row_index = 0; row_index < rows; row_index++)
{
for (int col_index = 0; col_index < cols; col_index++)
{
// print the pixels of image
printf("%3d", values[image_index*image_size+row_index*cols+col_index]);
}
printf("\n");
}
printf("\n");
}
free(values);
fclose(fp);
return 0;
}
int main(int argc, char *argv[])
{
if (-1 == read_lables())
{
return -1;
}
if (-1 == read_images())
{
return -1;
}
return 0;
}
下載并解壓出數(shù)據(jù)集文件train-images-idx3-ubyte和train-labels-idx1-ubyte放到源代碼所在目錄后,編譯并執(zhí)行:
gcc -o read_images read_images.c
./read_images
展示出來的效果如下:

一共有60000個圖片,從代碼可以看出數(shù)據(jù)集里存儲的實際就是圖片的像素
請尊重原創(chuàng),轉(zhuǎn)載請注明來源網(wǎng)站www.shareditor.com以及原始鏈接地址
softmax模型
我們在《 機器學習教程 十三-用scikit-learn做邏輯回歸 》中介紹了邏輯回歸模型。邏輯回歸是用于解決二類分類問題(使用sigmoid函數(shù)),而softmax模型是邏輯回歸模型的擴展,用來解決多類分類問題。
softmax意為柔和的最大值,也就是如果某個zj大于其他z,那么這個映射的分量就逼近于1,其他的分量就逼近于0,從而將其歸為此分類,多個分量對應的就是多分類,數(shù)學形式和sigmoid不同,如下:

它的特點是,所有的softmax加和為1,其實它表示的是一種概率,即x屬于某個分類的概率。
在做樣本訓練時,這里的xi計算方法是:

其中W是樣本特征的權(quán)重,xj是樣本的特征值,bi是偏置量。
詳細來說就是:假設某個模型訓練中我們設計兩個特征,他們的值分別是f1和f2,他們對于第i類的權(quán)重分別是0.2和0.8,偏置量是1,那么
xi=f1*0.2+f2*0.8+1
如果所有的類別都計算出x的值,如果是一個訓練好的模型,那么應該是所屬的那個類別對應的softmax值最大
softmax回歸算法也正是基于這個原理,通過大量樣本來訓練這里的W和b,從而用于分類的
tensorflow的優(yōu)點
tensorflow會使用外部語言計算復雜運算來提高效率,但是不同語言之間的切換和不同計算資源之間的數(shù)據(jù)傳輸耗費很多資源,因此它使用圖來描述一系列計算操作,然后一起傳給外部計算,最后結(jié)果只傳回一次,這樣傳輸代價最低,計算效率最高
舉個例子:
import tensorflow as tf
x = tf.placeholder(tf.float32, [None, 784])
這里的x不是一個實際的x,而是一個占位符,也就是一個描述,描述成了二維浮點型,后面需要用實際的值來填充,這就類似于printf("%d", 10)中的占位符%d,其中第一維是None表示可無限擴張,第二維是784個浮點型變量
如果想定義可修改的張量,可以這樣定義:
W = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))
其中W的維度是[784, 10],b的形狀是[10]
有了這三個變量,我們可以定義我們的softmax模型:
y = tf.nn.softmax(tf.matmul(x,W) + b)
這雖然定義,但是沒有真正的進行計算,因為這只是先用圖來描述計算操作
其中matmul是矩陣乘法,因為x的維度是[None, 784],W的維度是[784, 10],所以矩陣乘法得出的是[None, 10],這樣可以和向量b相加
softmax函數(shù)會計算出10維分量的概率值,也就是y的形狀是[10]
數(shù)字識別模型實現(xiàn)
基于上面定義的x、W、b,和我們定義的模型:
y = tf.nn.softmax(tf.matmul(x,W) + b)
我們需要定義我們的目標函數(shù),我們以交叉熵(衡量預測用于描述真相的低效性)為目標函數(shù),讓它達到最?。?/p>
