使用神经网络进行Python查询

时间:2016-01-25 18:48:07

标签: python neural-network

我正在尝试修改由软件开发人员(Kyle Dickerson)编写的代码,并将其编写为:

所以我有这段代码:

from __future__ import division

## Kyle Dickerson
## kyle.dickerson@gmail.com
## Jan 15, 2008
##
## Self-organizing map using scipy
## This code is licensed and released under the GNU GPL

## This code uses a square grid rather than hexagonal grid, as scipy    allows for fast square grid computation.
## I designed sompy for speed, so attempting to read the code may not be  very intuitive.
## If you're trying to learn how SOMs work, I would suggest starting with     Paras Chopras SOMPython code:
##  http://www.paraschopra.com/sourcecode/SOM/index.php
## It has a more intuitive structure for those unfamiliar  with scipy, however it is much slower.

## If you do use this code for something, please  let me know, I'd like to know if has been useful to anyone.

from random import *
from math import *
import sys
import scipy
import numpy
class SOM:

def __init__(self, height=4, width=4, FV_size=3, learning_rate=0.005):
    self.height = height
    self.width = width
    self.FV_size = FV_size
    self.radius = (height+width)/3
    self.learning_rate = learning_rate
    self.nodes = scipy.array([[ [random()*255 for 
     i in range(FV_size)]  for x in range(width)] for y in range(height)])


    self.nodes = scipy.array([[1,2,3],[4,5,6],[4,5,6],
   [4,5,6],[4,5,6],    [4,5,6],[4,5,6],[4,5,6],[4,5,6],
   [4,5,6],[4,5,6],[4,5,6],[4,5,6],[4,5,6],[4,5,6],[4,5,6]])



    print "SOM",self.nodes

  def train(self, iterations=1000, train_vector=[[]]):
    for t in range(len(train_vector)):
        train_vector[t] = scipy.array(train_vector[t])
    print "training",train_vector[t],t
    time_constant = iterations/log(self.radius)
    delta_nodes = scipy.array([[[0 for i in range(self.FV_size)] 
    for x in range(self.width)] for y in range(self.height)])

    for i in range(1, iterations+1):
        delta_nodes.fill(0)
        radius_decaying=self.radius*exp(-1.0*i/time_constant)
        rad_div_val = 2 * radius_decaying * i
                                                                                     learning_rate_decaying=self.learning_rate*exp(-1.0*i/time_constant)
         sys.stdout.write("\rTraining Iteration: 
       " + str(i) + "/" +  str(iterations))

        for j in range(len(train_vector)):
            best = self.best_match(train_vector[j])
            for loc in self.find_neighborhood(best, radius_decaying):
                influence = exp( (-1.0 * (loc[2]**2)) / rad_div_val)
                inf_lrd = influence*learning_rate_decaying

                delta_nodes[loc[0],loc[1]] += inf_lrd*
       (train_vector[j]-  self.nodes[loc[0],loc[1]])
        self.nodes += delta_nodes
    sys.stdout.write("\n")
 # Returns a list of points which live within 'dist' of 'pt'
 # Uses the Chessboard distance
  # pt is (row, column)
  def find_neighborhood(self, pt, dist):
    min_y = max(int(pt[0] - dist), 0)
    max_y = min(int(pt[0] + dist), self.height)
    min_x = max(int(pt[1] - dist), 0)
    max_x = min(int(pt[1] + dist), self.width)
    neighbors = []
    for y in range(min_y, max_y):
        for x in range(min_x, max_x):
            dist = abs(y-pt[0]) + abs(x-pt[1])
            neighbors.append((y,x,dist))
    return neighbors

# Returns location of best match, uses Euclidean distance
# target_FV is a scipy array
def best_match(self, target_FV):
    loc = scipy.argmin((((self.nodes - target_FV)**2).sum(axis=2))**0.5)
    r = 0
    while loc > self.width:
        loc -= self.width
        r += 1
    c = loc
    return (r, c)

# returns the Euclidean distance between two Feature Vectors
# FV_1, FV_2 are scipy arrays
def FV_distance(self, FV_1, FV_2):
    return (sum((FV_1 - FV_2)**2))**0.5

 if __name__ == "__main__":
     print "Initialization..."

      colors = [ [0, 0, 0], [0, 0, 255], [0, 255, 0], 
          [0, 255, 255], [255, 0,  0], [255, 0, 255],  
         [255, 255, 0], [255, 255, 255]]
      width = 32
     height = 32
     color_som = SOM(width,height,3,0.05)
     print "Training colors..."
     color_som.train(1000, colors)
     try:
         from PIL import Image
         print "Saving Image: sompy_test_colors.png..."
         img = Image.new("RGB", (width, height))
         for r in range(height):
             for c in range(width):
                   img.putpixel((c,r),(int(color_som.nodes[r,c,0]),  
                        int(color_som.nodes[r,c,1]),       int(color_som.nodes[r,c,2])))
         print "color nodes",color_som.nodes
         img = img.resize((width*10, height*10),Image.NEAREST)
         img.save("sompy_test_colors.png")
    except:
         print "Error saving the image, do you have PIL (Python Imaging       Library) installed?"

但是当我试图从

开始
self.nodes = scipy.array([[ [random()*255 
     for i in range(FV_size)] for x in range(width)] 
     for y in range(height)])

在原始代码中是这样的:

     self.nodes = scipy.array([[1,2,3],[4,5,6],[4,5,6],
       [4,5,6],[4,5,6],[4,5,6],[4,5,6],[4,5,6],[4,5,6],[4,5,6],
     [4,5,6],[4,5,6],[4,5,6],[4,5,6],[4,5,6],[4,5,6]])

我收到错误消息:

File "sompy5.py", line 112, in <module>
color_som.train(1000, colors)
File "sompy5.py", line 65, in train
best = self.best_match(train_vector[j])
 File "sompy5.py", line 92, in best_match
loc = scipy.argmin((((self.nodes - target_FV)**2).sum(axis=2))**0.5)
 File "/usr/lib/python2.7/dist-packages/numpy/core/_methods.py", 
 line 25, in   _sum
  out=out, keepdims=keepdims)
  ValueError: 'axis' entry is out of bounds

是否需要做一些事情才能让矢量匹配?

1 个答案:

答案 0 :(得分:0)

这部分是一个三维数组(开始参数的3个方括号):

self.nodes = scipy.array([[ [random()*255 for 
 i in range(FV_size)]  for x in range(width)] for y in range(height)])

这部分是一个二维数组:

self.nodes = scipy.array([[1,2,3],[4,5,6],[4,5,6],
   [4,5,6],[4,5,6],[4,5,6],[4,5,6],[4,5,6],[4,5,6],[4,5,6],
 [4,5,6],[4,5,6],[4,5,6],[4,5,6],[4,5,6],[4,5,6]])

因此,您需要将self.nodes转换为适当的3-D数组。

编辑:所需语法的示例:

self.nodes = scipy.array([[ [1,2,3],[4,5,6]] , [[7,8,9],[10,11,12]]])

print(self.nodes)
>>> array([[[ 1, 2, 3],
            [ 4, 5, 6]],

           [[ 7, 8, 9],
            [10, 11, 12]]])

编辑2:

另一个选择是构建线性数组,然后重塑形状():

myarray = scipy.array([1,2,3,4,5,6,7,8,9,10,11,12])
myarray = myarray.reshape( (2, 2, 3) )  ## 3 numbers for 3 dimensions, but the product must be the same as the number of elements of the original array
print(myarray)
>>> array([[[ 1, 2, 3],
            [ 4, 5, 6]],

           [[ 7, 8, 9],
            [10, 11, 12]]])