1

I tried translating my R code to Julia, but my perceptron function in the julia code is in an infinite loop and I cannot find my mistake.

what the code does: 1. make 100 random data points in [-1,1]^2 2. generate 2 random points in [-1,1], the linear line f between them serves as a linear separator 3. classify the 100 points in 2 classes (-1 and 1) below and above f, ylist is a list of -1 and 1s depending on the class. 4. build a hypothesis for f with the perception algorithm

R Code:

#library(MASS)
#library(ggplot2)
n <- 100
datam <- matrix(c(rep(1,n), 2*runif(n)-1, 2*runif(n)-1), n)
a <- 2*runif(2)-1
b <- 2*runif(2)-1
f <- lm(a ~ b)
fff <- coef(f)
test <- c(1, fff[1], fff[2])
ylist <- sign(datam %*% test)

perceptron = function(datam, ylist) {
w <- c(1,0,0)
made.mistake = TRUE 
while (made.mistake) {
made.mistake=FALSE 
for (i in 1:n) {
  if (ylist[i] != sign(t(w) %*% datam[i,])) {
    w <- w + ylist[i]*datam[i,]
    made.mistake=TRUE 
  }
}
}
return(w=w)
}

perceptron(datam,ylist)

julia code:

n = 100

fp = [2*rand(2)-1 for i = 1:2 ]

A = [ones(n,1) c=2*rand(n)-1 d=2*rand(n)-1]  

m = (fp[2][2]-fp[1][2])/(fp[2][1]-fp[1][1])

b = fp[2][2]-m*fp[2][1]

funkt = [1 m b]

ylist = sign(A*funkt') 

w = A\ylist


function perceptron(data, y)
v = [1 0 0]
mistake = true
while mistake
    mistake = false
    for i = 1:n
        if y[i] != sign(v*data[i,:]')
            v = v + y[i]*data[i,:]
            mistake = true
        end
    end
end
return v
end

perceptron(A,ylist)

I'm always open for other code improvements

4

1 回答 1

3

To give a more complete description of the issues behind the solution you found on your own, Julia treats a scalar differently from an array with one element:

julia> 5 == [5]
false

So a scalar, y[i], will never test as being equal to a matrix, v*data[i,:]'.

Your solution, to write y[i,:], ensures that both the left and right sides are matrices. An alternative is to ensure that both sides are scalars, which you could do by extracting the first element of the RHS, e.g., sign((v*data[i,:]')[1]).

However, there are somewhat better ways to do this (which only matter if you want better performance). A few tips:

  • In general, if you want a 1-dimensional object, you should use commas rather than spaces:

    funkt = [1,m,b]  # Gives a 1-d array, [1 m b] gives a 2-d array
    ylist = sign(A*funkt)
    
  • Because of the way memory is stored, it's much more efficient to extract columns than rows, so you might consider defining A as the transpose of what you have here.

  • The dot function takes two vectors and computes their dot product, which is a scalar.

于 2013-12-31T11:25:49.467 回答