1

I am trying to implement multi-varibale linear regression using tensorflow. I have a csv file with 200 rows and 3 columns (features) with the last column as output. Something like this: enter image description here

I have written the following code:

from __future__ import print_function

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import csv
import pandas
rng = np.random


# Parameters
learning_rate = 0.01
training_epochs = 1000
display_step = 50

I get the data from the file using pandas and store it:

# Training Data
dataframe = pandas.read_csv("Advertising.csv", delim_whitespace=True, header=None)
dataset = dataframe.values

X1,X2,X3,y1 = [],[],[],[]
for i in range(1,len(dataset)):
    X = dataset[i][0]
    X1.append(np.float32(X.split(",")[1]))
    X2.append(np.float32(X.split(",")[2]))
    X3.append(np.float32(X.split(",")[3]))
    y1.append(np.float32(X.split(",")[4]))
X = np.column_stack((X1,X2))
X = np.column_stack((X,X3))

I assign the placeholders and variables and the linear regression model:

n_samples = len(X1)
#print(n_samples) = 17
# tf Graph Input
X_1 = tf.placeholder(tf.float32, [3, None])
Y = tf.placeholder(tf.float32, [None])

# Set model weights
W1 = tf.Variable(rng.randn(), [n_samples,3])
b = tf.Variable(rng.randn(), [n_samples])



# Construct a linear model
pred = tf.add(tf.matmul(W1, X_1), b)

# Mean squared error
cost = tf.reduce_sum(tf.pow(pred-Y, 2))/(2*n_samples)
# Gradient descent
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)

# Initializing the variables
init = tf.global_variables_initializer()

# Launch the graph
with tf.Session() as sess:
    sess.run(init)

    # Fit all training data
    for epoch in range(training_epochs):
        for (x1, y) in zip(X, y1):
            sess.run(optimizer, feed_dict={X_1: x1, Y: y})
        # Display logs per epoch step
        if (epoch+1) % display_step == 0:
            c = sess.run(cost, feed_dict={X_1: x1, Y: y})
            print("Epoch:", '%04d' % (epoch+1), "cost=", "{:.9f}".format(c), \
                "Weights=", sess.run(W1),"b=", sess.run(b))

I get the following error which I am not able to debug:

ValueError: Shape must be rank 2 but is rank 0 for 'MatMul' (op: 'MatMul') with input shapes: [], [3,?].

Can you help me with hot to solve this?

Thanks in advance.

Nadjib Mami
  • 5,736
  • 9
  • 37
  • 49
Sarvagya Gupta
  • 861
  • 3
  • 13
  • 28

2 Answers2

1

tf.variable doesn't take inputs as you are thinking, the second parameter is not shape. To set the shape of the variable you do this with the initializer (the first parameter). see https://www.tensorflow.org/api_docs/python/tf/Variable

Your code

# Set model weights
W1 = tf.Variable(rng.randn(), [n_samples,3])
b = tf.Variable(rng.randn(), [n_samples])

My suggested change

initial1 = tf.constant(rng.randn(), dtype=tf.float32, shape=[n_samples,3])
initial2 = tf.constant(rng.randn(), dtype=tf.float32, shape=[n_samples,3])
W1 = tf.Variable(initial_value=initial1) 
b = tf.Variable(initial_value=initial2)

In answer to the additional issues which arise after fixing the initial question the following code runs - but there still might be some logical error which you need to think about - like your #display logs per epoch step.

from __future__ import print_function

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import csv
import pandas
rng = np.random


# Parameters
learning_rate = 0.01
training_epochs = 1000
display_step = 50
# Training Data
#Created some fake data
dataframe = [[230.1,37.8,69.2,22.1],[2230.1,32.8,61.2,21.1]] #pandas.read_csv("Advertising.csv", delim_whitespace=True, header=None)
dataset = dataframe

X1,X2,X3,y1 = [],[],[],[]
for i in range(0,len(dataset)):
    X = dataset[i][0]
    X1.append(np.float32(dataset[i][0]))
    X2.append(np.float32(dataset[i][1]))
    X3.append(np.float32(dataset[i][2]))
    y1.append(np.float32(dataset[i][3]))
#X=np.array([X1,X2,X3])
X = np.column_stack((X1,X2,X3)) ##MYEDIT: This combines all three values. If you find you need to stack in a different way then you will need to ensure the shapes below match this shape.
#X = np.column_stack((X,X3))

n_samples = len(X1)
#print(n_samples) = 17
# tf Graph Input
X_1 = tf.placeholder(tf.float32, [ None,3])##MYEDIT: Changed order
Y = tf.placeholder(tf.float32, [None])
# Set model weights
initial1 = tf.constant(rng.randn(), dtype=tf.float32, shape=[3,1]) ###MYEDIT: change order and you are only giving 1 sample at a time with your method of calling
initial2 = tf.constant(rng.randn(), dtype=tf.float32, shape=[3,1])
W1 = tf.Variable(initial_value=initial1)
b = tf.Variable(initial_value=initial2)


mul=tf.matmul(W1, X_1)   ##MYEDIT: remove matmul from pred for clarity and shape checking
# Construct a linear model
pred = tf.add(mul, b)

# Mean squared error
cost = tf.reduce_sum(tf.pow(pred-Y, 2))/(2*n_samples)
# Gradient descent
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)

# Initializing the variables
init = tf.global_variables_initializer()

# Launch the graph
with tf.Session() as sess:
    sess.run(init)

    # Fit all training data
    for epoch in range(training_epochs):
        for (x1, y) in zip(X, y1):
            Xformatted=np.array([x1])  #has shape (1,3)  #MYEDIT: separated this to demonstrate shapes
            yformatted=np.array([y])  #shape (1,)  #MYEDIT: separated this to demonstrate shapes
                                                    #NB. X_1 shape is (?,3)   and Y shape is (?,)
            sess.run(optimizer, feed_dict={X_1: Xformatted, Y: yformatted})
        # Display logs per epoch step
        if (epoch+1) % display_step == 0:
            c = sess.run(cost, feed_dict={X_1: Xformatted, Y: yformatted})   #NB. x1 an y are out of scope here - you will only get the last values. Double check if this is what you meant.
            print("Epoch:", '%04d' % (epoch+1), "cost=", "{:.9f}".format(c), \
                "Weights=", sess.run(W1),"b=", sess.run(b))
The Puternerd
  • 632
  • 4
  • 12
  • Hey, I tried you solution and I got the following error: `ValueError: Cannot feed value of shape (3,) for Tensor 'Placeholder:0', which has shape '(3, ?)'` – Sarvagya Gupta Apr 21 '17 at 20:32
  • That's a different question, which I need to repost all your code to answer - not just the snippet relating to this question. Your problem now is that your inputs x1 and y do not match your placeholders shape. Inspect the shape of these and you will see shapes x1 being (3,) and y is a float. make x1=[x1] and y=[y1] and you will find the shapes are now x as (1,3) and y (1,). But you are also going to find that your line X=np.column_stack should be X=np.column_stack((X1,X2,X3)) which changes the shapes for your X_1 placeholder and your initializer is also the incorrect shape for your input. – The Puternerd Apr 22 '17 at 00:41
  • I will amend my answer to include the additional changes, but could you also amend your question to add the extra issues for completeness. – The Puternerd Apr 22 '17 at 00:43
  • I cannot thank you enough for the help. I am new to tensorflow and I apologize for the mixup. Thanks a lot!!! – Sarvagya Gupta Apr 22 '17 at 20:52
  • My pleasure. Keep asking questions and keep selecting answers, there are many people happy to help. – The Puternerd Apr 23 '17 at 03:43
0

You need to feed a matrix into tf.matmul(W1, X_1). Check the types for your W1 and X_1 for your code.

See the question here for more details

Community
  • 1
  • 1
zglin
  • 2,891
  • 2
  • 15
  • 26