lolamontes69

Ch4 Ex8-Collective Intelligence (Additional layers)

Jun 28th, 2013
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.50 KB | None | 0 0
  1. """ Chapter 4 Exercise 8: Additional layers. Your neural network has only one hidden layer.
  2.    Update the class to support an arbitrary number of hidden layers, which can be specified upon initialization.
  3. """
  4.  
  5. from math import tanh
  6. from pysqlite2 import dbapi2 as sqlite
  7.  
  8. def dtanh(y):
  9.     return 1.0-y*y
  10.  
  11. class searchnet:
  12.     def __init__(self,dbname):
  13.         self.con=sqlite.connect(dbname)
  14.  
  15.     def __del__(self):
  16.         self.con.close()
  17.  
  18.     def maketables(self, hlayer=0):
  19.         for a in range(hlayer):
  20.             self.con.execute('create table hiddennode%s(create_key)' % a)
  21.             self.con.execute('create table wordhidden%s(fromid,toid,strength)' % a)
  22.             self.con.execute('create table hiddenurl%s(fromid,toid,strength)' % a)
  23.         self.con.commit()
  24.  
  25.     def getstrength(self,fromid,toid,layer,hlayer):
  26.         if layer==0: table='wordhidden%s' % hlayer
  27.         else: table='hiddenurl%s' % hlayer
  28.         res=self.con.execute('select strength from %s where fromid=%d and toid=%d' % (table,fromid,toid)).fetchone()
  29.         if res==None:
  30.             if layer==0: return -0.2
  31.             if layer==1: return 0
  32.         return res[0]
  33.  
  34.     def setstrength(self,fromid,toid,layer,strength,hlayer):
  35.         if layer==0: table='wordhidden%s' % hlayer
  36.         else: table='hiddenurl%s' % hlayer
  37.         res=self.con.execute('select rowid from %s where fromid=%d and toid=%d' % (table,fromid,toid)).fetchone()
  38.         if res==None:
  39.             self.con.execute('insert into %s (fromid,toid,strength) values (%d,%d,%f)' % (table,fromid,toid,strength))
  40.         else:
  41.             rowid=res[0]
  42.             self.con.execute('update %s set strength=%f where rowid=%d' % (table,strength,rowid))
  43.  
  44.     def generatehiddennode(self,wordids,urls,hlayer):
  45.         if len(wordids)>3: return None
  46.         # Check if we already created a node for this set of words
  47.         createkey='_'.join(sorted([str(wi) for wi in wordids]))
  48.         res=self.con.execute("select rowid from hiddennode%s where create_key='%s'" % (hlayer,createkey)).fetchone()
  49.  
  50.         # If not create it
  51.         if res==None:
  52.             cur=self.con.execute("insert into hiddennode%s (create_key) values ('%s')" % (hlayer,createkey))
  53.             hiddenid=cur.lastrowid
  54.             # Put in some default weights
  55.             for wordid in wordids:
  56.                 self.setstrength(wordid,hiddenid,0,1.0/len(wordids),hlayer)
  57.             for urlid in urls:
  58.                 self.setstrength(hiddenid,urlid,1,0.1,hlayer)
  59.             self.con.commit()
  60.  
  61.     def getallhiddenids(self,wordids,urlids,hlayer):
  62.         l1={}
  63.         for wordid in wordids:
  64.             cur=self.con.execute('select toid from wordhidden%s where fromid=%d' % (hlayer,wordid))
  65.             for row in cur: l1[row[0]]=1
  66.         for urlid in urlids:
  67.             cur=self.con.execute('select fromid from hiddenurl%s where toid=%d' % (hlayer,urlid))
  68.             for row in cur: l1[row[0]]=1
  69.         return l1.keys()
  70.  
  71.     def setupnetwork(self,wordids,urlids,hlayer):
  72.         # Value lists
  73.         self.wordids=wordids
  74.         self.hiddenids=self.getallhiddenids(wordids,urlids,hlayer)
  75.         self.urlids=urlids
  76.  
  77.         # Node outputs         strengths set to default values
  78.         self.ai = [1.0]*len(self.wordids)
  79.         self.ah = [1.0]*len(self.hiddenids)
  80.         self.ao = [1.0]*len(self.urlids)
  81.  
  82.         # Create weights matrix
  83.         self.wi =[[self.getstrength(wordid,hiddenid,0,hlayer) for hiddenid in self.hiddenids] for wordid in self.wordids]
  84.         self.wo =[[self.getstrength(hiddenid,urlid,1,hlayer) for urlid in self.urlids] for hiddenid in self.hiddenids]
  85.  
  86.     def feedforward(self):
  87.         # the only inputs are the query words
  88.         for i in range(len(self.wordids)):
  89.             self.ai[i] = 1.0
  90.  
  91.         # hidden activations
  92.         for j in range(len(self.hiddenids)):
  93.             sum = 0.0
  94.             for i in range(len(self.wordids)):
  95.                 sum = sum + self.ai[i] * self.wi[i][j]
  96.             self.ah[j] = tanh(sum)
  97.  
  98.         # output activations
  99.         for k in range(len(self.urlids)):
  100.             sum = 0.0
  101.             for j in range(len(self.hiddenids)):
  102.                 sum = sum + self.ah[j] * self.wo[j][k]
  103.             self.ao[k] = tanh(sum)
  104.  
  105.         return self.ao[:]
  106.  
  107.     def getresult(self,wordids,urlids,hlayer):
  108.         self.setupnetwork(wordids,urlids,hlayer)
  109.         return self.feedforward()
  110.  
  111.     def backPropagate(self,targets, N=0.5):
  112.         # calculate errors for output
  113.         output_deltas = [0.0]*len(self.urlids)
  114.         for k in range(len(self.urlids)):
  115.             error = targets[k]-self.ao[k]
  116.             output_deltas[k] = dtanh(self.ao[k])*error
  117.  
  118.         # calculate errors for hidden layer
  119.         hidden_deltas = [0.0]*len(self.hiddenids)
  120.         for j in range(len(self.hiddenids)):
  121.             error = 0.0
  122.             for k in range(len(self.urlids)):
  123.                 error = error+output_deltas[k]*self.wo[j][k]
  124.             hidden_deltas[j] = dtanh(self.ah[j])*error
  125.  
  126.         # update output weights
  127.         for j in range(len(self.hiddenids)):
  128.             for k in range(len(self.urlids)):
  129.                 change=output_deltas[k]*self.ah[j]
  130.                 self.wo[j][k] = self.wo[j][k] + N*change
  131.  
  132.         # update input weights
  133.         for i in range(len(self.wordids)):
  134.             for j in range(len(self.hiddenids)):
  135.                 change = hidden_deltas[j]*self.ai[i]
  136.                 self.wi[i][j] = self.wi[i][j] + N*change
  137.  
  138.     def trainquery(self,wordids,urlids,selectedurl,hlayer):
  139.         # generate a hiddennode if neccessary
  140.         self.generatehiddennode(wordids,urlids,hlayer)
  141.  
  142.         self.setupnetwork(wordids,urlids,hlayer)
  143.         self.feedforward()
  144.         targets=[0.0]*len(urlids)
  145.         targets[urlids.index(selectedurl)]=1.0
  146.         error = self.backPropagate(targets)
  147.         self.updatedatabase(hlayer)
  148.  
  149.     def updatedatabase(self,hlayer):
  150.         # set them to database values
  151.         for i in range(len(self.wordids)):
  152.             for j in range(len(self.hiddenids)):
  153.                 self.setstrength(self.wordids[i],self.hiddenids[j],0,self.wi[i][j],hlayer)
  154.         for j in range(len(self.hiddenids)):
  155.             for k in range(len(self.urlids)):
  156.                 self.setstrength(self.hiddenids[j],self.urlids[k],1,self.wo[j][k],hlayer)
  157.         self.con.commit()
  158.  
  159. """
  160. ####################
  161. # Testing it works #
  162. ####################
  163. With one hidden layer -first save as nn_redux.py obviously
  164. **********************************************************
  165. import nn_redux as nn
  166. mynet=nn.searchnet('nn_redux.db')
  167. mynet.maketables(1)       --- when number of hiddenlayers is 1 hlayer=0
  168.                          --- either that or use ...hiddennode%s(create_key)' % a+1)
  169. wWorld,wRiver,wBank=101,102,103
  170. uWorldBank,uRiver,uEarth=201,202,203
  171. mynet.generatehiddennode([wWorld,wBank],[uWorldBank,uRiver,uEarth],0)
  172.  
  173. # test hiddennode exists
  174. for c in mynet.con.execute('select * from hiddennode0'): print c
  175. for c in mynet.con.execute('select * from wordhidden0'): print c
  176. for c in mynet.con.execute('select * from hiddenurl0'): print c
  177. mynet.getresult([wWorld,wBank],[uWorldBank,uRiver,uEarth],0)
  178.  
  179. # train the neural net
  180. mynet.trainquery([wWorld,wBank],[uWorldBank,uRiver,uEarth],uWorldBank,0)
  181. mynet.getresult([wWorld,wBank],[uWorldBank,uRiver,uEarth],0)
  182. -------------------------------------------------------------------------------
  183.  
  184. With two hidden layer -first save as nn_redux.py obviously
  185. ***********************************************************
  186. import nn_redux as nn
  187. mynet=nn.searchnet('nn_redux.db')
  188. mynet.maketables(2)
  189.  
  190. wWorld,wRiver,wBank=101,102,103
  191. uWorldBank,uRiver,uEarth=201,202,203
  192. mynet.generatehiddennode([wWorld,wBank],[uWorldBank,uRiver,uEarth],0)
  193. mynet.generatehiddennode([wWorld,wBank],[uWorldBank,uRiver,uEarth],1)
  194.  
  195. # test hiddennode exists
  196. for c in mynet.con.execute('select * from hiddennode0'): print c
  197. for c in mynet.con.execute('select * from hiddennode1'): print c
  198. mynet.getresult([wWorld,wBank],[uWorldBank,uRiver,uEarth],0)
  199. mynet.getresult([wWorld,wBank],[uWorldBank,uRiver,uEarth],1)
  200.  
  201. # train the neural net
  202. mynet.trainquery([wWorld,wBank],[uWorldBank,uRiver,uEarth],uWorldBank,0)
  203. mynet.trainquery([wWorld,wBank],[uWorldBank,uRiver,uEarth],uRiver,1)
  204. mynet.getresult([wWorld,wBank],[uWorldBank,uRiver,uEarth],0)
  205. mynet.getresult([wWorld,wBank],[uWorldBank,uRiver,uEarth],1)
  206. -------------------------------------------------------------------------------
  207.  
  208. #################################################
  209. # Adding the hlayer variable to searchengine.py #
  210. #################################################
  211.  
  212.    The hlayer could be used like a unique user id to give
  213.    specifically tailored results.
  214.  
  215.    def query(self,q,hlayer):
  216.        rows,wordids=self.getmatchrows(q.lower())
  217.        if rows == "Nothing":
  218.            return ['%s Not in database' %q]
  219.        scores=self.getscoredlist(rows,wordids,hlayer)...........
  220.  
  221.    def getscoredlist(self,rows,wordids,hlayer):
  222.        totalscores=dict([(row[0],0) for row in rows])...........
  223. ..........
  224.        weights=[(1.0,self.nnscore(rows, wordids, hlayer))]
  225.  
  226.  
  227.    def nnscore(self,rows,wordids,hlayer):
  228.        # Get unique URL IDs as an ordered list
  229.        urlids=[urlid for urlid in set([row[0] for row in rows])]
  230.        nnres=mynet.getresult(wordids,urlids,hlayer)
  231.        scores=dict([(urlids[i],nnres[i]) for i in range(len(urlids))])
  232.        return self.normalizescores(scores)
  233.        
  234. -------------------------------------------------------------------------------
  235. """
Advertisement
Add Comment
Please, Sign In to add comment