# 使用 NumPy 实现人工神经网络来分类图像

### 特征提取

RGB颜色空间不会将颜色信息与其他类型的信息（如照明）隔离开来。 因此，如果RGB用于表示图像，则3个通道将参与计算。 出于这个原因，最好使用将颜色信息隔离成单个通道（如HSV）的颜色空间。 在这种情况下，颜色通道是色调通道（H）。 下图显示了之前呈现的4个样本的色调通道。 我们可以注意到每个图像的色调值与其他图像的不同之处。

```import numpy`import skimage.io, skimage.color``import matplotlib.pyplot````
````raspberry = skimage.io.imread(fname="raspberry.jpg", as_grey=False)``apple = skimage.io.imread(fname="apple.jpg", as_grey=False)``mango = skimage.io.imread(fname="mango.jpg", as_grey=False)``lemon = skimage.io.imread(fname="lemon.jpg", as_grey=False)````
````apple_hsv = skimage.color.rgb2hsv(rgb=apple)``mango_hsv = skimage.color.rgb2hsv(rgb=mango)``raspberry_hsv = skimage.color.rgb2hsv(rgb=raspberry)``lemon_hsv = skimage.color.rgb2hsv(rgb=lemon)````
````fruits = ["apple", "raspberry", "mango", "lemon"]``hsv_fruits_data = [apple_hsv, raspberry_hsv, mango_hsv, lemon_hsv]``idx = 0``for hsv_fruit_data in hsv_fruits_data:``fruit = fruits[idx]``hist = numpy.histogram(a=hsv_fruit_data[:, :, 0], bins=360)``matplotlib.pyplot.bar(left=numpy.arange(360), height=hist[0])``matplotlib.pyplot.savefig(fruit+"-hue-histogram.jpg", bbox_inches="tight")``matplotlib.pyplot.close("all")``idx = idx + 1````

```import numpy`import skimage.io, skimage.color, skimage.feature``import os``import pickle````
````fruits = ["apple", "raspberry", "mango", "lemon"]``#492+490+490+490=1,962````
````dataset_features = numpy.zeros(shape=(1962, 360))``outputs = numpy.zeros(shape=(1962))``idx = 0``class_label = 0````
````for fruit_dir in fruits:``  curr_dir = os.path.join(os.path.sep, fruit_dir)``  all_imgs = os.listdir(os.getcwd()+curr_dir)``  for img_file in all_imgs:``    fruit_data = skimage.io.imread(fname=os.getcwd()+curr_dir+img_file, as_grey=False)``    fruit_data_hsv = skimage.color.rgb2hsv(rgb=fruit_data)``    hist = numpy.histogram(a=fruit_data_hsv[:, :, 0], bins=360)``    dataset_features[idx, :] = hist[0]``    outputs[idx] = class_label``    idx = idx + 1``  class_label = class_label + 1````
````with open("dataset_features.pkl", "wb") as f:``  pickle.dump("dataset_features.pkl", f)````
````with open("outputs.pkl", "wb") as f:``  pickle.dump(outputs, f)````

### ANN实现

```import numpy`import pickle````
````def sigmoid(inpt):``  return 1.0 / (1 + numpy.exp(-1 * inpt))````
````f = open("dataset_features.pkl", "rb")``data_inputs2 = pickle.load(f)``f.close()````
````features_STDs = numpy.std(a=data_inputs2, axis=0)``data_inputs = data_inputs2[:, features_STDs > 50]````
````f = open("outputs.pkl", "rb")``data_outputs = pickle.load(f)``f.close()````
````HL1_neurons = 150``input_HL1_weights = numpy.random.uniform(low=-0.1, high=0.1,``    size=(data_inputs.shape[1], HL1_neurons))````
````HL2_neurons = 60``HL1_HL2_weights = numpy.random.uniform(low=-0.1, high=0.1,``    size=(HL1_neurons, HL2_neurons))````
````output_neurons = 4``HL2_output_weights = numpy.random.uniform(low=-0.1, high=0.1,``    size=(HL2_neurons, output_neurons))````
````H1_outputs = numpy.matmul(a=data_inputs[0, :], b=input_HL1_weights)``H1_outputs = sigmoid(H1_outputs)``H2_outputs = numpy.matmul(a=H1_outputs, b=HL1_HL2_weights)``H2_outputs = sigmoid(H2_outputs)``out_otuputs = numpy.matmul(a=H2_outputs, b=HL2_output_weights)````
````predicted_label = numpy.where(out_otuputs == numpy.max(out_otuputs))[0][0]``print("Predicted class : ", predicted_label)````

```import numpy`import pickle````
````def sigmoid(inpt):``  return 1.0 / (1 + numpy.exp(-1 * inpt))````
````def relu(inpt):``  result = inpt``  result[inpt < 0] = 0``  return result````
````def update_weights(weights, learning_rate):``  new_weights = weights - learning_rate * weights``  return new_weights````
````def train_network(num_iterations, weights, data_inputs, data_outputs, learning_rate, activation="relu"):``  for iteration in range(num_iterations):``    print("Itreation ", iteration)``    for sample_idx in range(data_inputs.shape[0]):``      r1 = data_inputs[sample_idx, :]``      for idx in range(len(weights) - 1):``       curr_weights = weights[idx]``       r1 = numpy.matmul(a=r1, b=curr_weights)``       if activation == "relu":``         r1 = relu(r1)``       elif activation == "sigmoid":``         r1 = sigmoid(r1)``    curr_weights = weights[-1]``    r1 = numpy.matmul(a=r1, b=curr_weights)``    predicted_label = numpy.where(r1 == numpy.max(r1))[0][0]``    desired_label = data_outputs[sample_idx]``    if predicted_label != desired_label:``      weights = update_weights(weights,``        learning_rate=0.001)``  return weights````
````def predict_outputs(weights, data_inputs, activation="relu"):``  predictions = numpy.zeros(shape=(data_inputs.shape[0]))``  for sample_idx in range(data_inputs.shape[0]):``    r1 = data_inputs[sample_idx, :]``      for curr_weights in weights:``        r1 = numpy.matmul(a=r1, b=curr_weights)``      if activation == "relu":``        r1 = relu(r1)``      elif activation == "sigmoid":``        r1 = sigmoid(r1)``    predicted_label = numpy.where(r1 == numpy.max(r1))[0][0]``    predictions[sample_idx] = predicted_label``  return predictions````
````f = open("dataset_features.pkl", "rb")``data_inputs2 = pickle.load(f)``f.close()````
````features_STDs = numpy.std(a=data_inputs2, axis=0)``data_inputs = data_inputs2[:, features_STDs > 50]````
````f = open("outputs.pkl", "rb")``data_outputs = pickle.load(f)``f.close()````
````HL1_neurons = 150``input_HL1_weights = numpy.random.uniform(low=-0.1, high=0.1,``size=(data_inputs.shape[1], HL1_neurons))````
````HL2_neurons = 60``HL1_HL2_weights = numpy.random.uniform(low=-0.1, high=0.1,``size=(HL1_neurons, HL2_neurons))````
````output_neurons = 4``HL2_output_weights = numpy.random.uniform(low=-0.1, high=0.1,``size=(HL2_neurons, output_neurons))````
````weights = numpy.array([input_HL1_weights,``  HL1_HL2_weights,``  HL2_output_weights])````
````weights = train_network(num_iterations=10,``  weights=weights,``  data_inputs=data_inputs,``  data_outputs=data_outputs,``  learning_rate=0.01,``  activation="relu")````
````predictions = predict_outputs(weights, data_inputs)``num_flase = numpy.where(predictions != data_outputs)[0]``print("num_flase ", num_flase.size)````