serizba / cppflow

Run TensorFlow models in C++ without installation and without Bazel
https://serizba.github.io/cppflow/
MIT License
779 stars 177 forks source link

I'm getting error "No operation named serving_default_input_1 exists" #151

Closed dacalalic closed 2 years ago

dacalalic commented 2 years ago

I'm getting this runtime error every time I try to make a prediction with my model. Error is correct there is no such operation, list of all operations are as follow: Op: conv2d_2/kernel Op: conv2d_2/kernel/Read/ReadVariableOp Op: conv2d_2/bias Op: conv2d_2/bias/Read/ReadVariableOp Op: conv2d_3/kernel Op: conv2d_3/kernel/Read/ReadVariableOp Op: conv2d_3/bias Op: conv2d_3/bias/Read/ReadVariableOp Op: dense_3/kernel Op: dense_3/kernel/Read/ReadVariableOp Op: dense_3/bias Op: dense_3/bias/Read/ReadVariableOp Op: dense_4/kernel Op: dense_4/kernel/Read/ReadVariableOp Op: dense_4/bias Op: dense_4/bias/Read/ReadVariableOp Op: dense_5/kernel Op: dense_5/kernel/Read/ReadVariableOp Op: dense_5/bias Op: dense_5/bias/Read/ReadVariableOp Op: SGD/iter Op: SGD/iter/Read/ReadVariableOp Op: SGD/decay Op: SGD/decay/Read/ReadVariableOp Op: SGD/learning_rate Op: SGD/learning_rate/Read/ReadVariableOp Op: SGD/momentum Op: SGD/momentum/Read/ReadVariableOp Op: total Op: total/Read/ReadVariableOp Op: count Op: count/Read/ReadVariableOp Op: total_1 Op: total_1/Read/ReadVariableOp Op: count_1 Op: count_1/Read/ReadVariableOp Op: NoOp Op: Const Op: serving_default_conv2d_2_input Op: StatefulPartitionedCall Op: saver_filename Op: StatefulPartitionedCall_1 Op: StatefulPartitionedCall_2

My model is trained in Python and it's a convolutional neural network based on LeNet5 and class that represents it is:

`class LeNet5: def init(self): self.model = Sequential() self.model.add(Conv2D(24, 5, input_shape=(64, 64, 3), padding='same', activation='relu')) self.model.add(Dropout(0.65)) self.model.add(MaxPool2D(pool_size=(2, 2))) self.model.add(Conv2D(64, 5, padding='same', activation='relu')) self.model.add(Dropout(0.65)) self.model.add(MaxPool2D(pool_size=(2, 2))) self.model.add(Flatten()) self.model.add(Dense(480, activation='relu')) self.model.add(Dropout(0.67)) self.model.add(Dense(84, activation='relu')) self.model.add(Dropout(0.67)) self.model.add(Dense(43, activation='softmax'))

def compile(self):
    self.model.compile(optimizer=SGD(lr=0.0005),\
                       loss="categorical_crossentropy",\
                       metrics=["accuracy"])

def train(self, trainData, trainLabels, epochs_num):
    return self.model.fit(trainData, trainLabels, batch_size=32, epochs=epochs_num, verbose=1)

def evaluate(self, testData, testLabels):
    (loss, accuracy) = self.model.evaluate(testData, testLabels, batch_size=32, verbose=1)
    print("accuracy: {:.2f}%".format(accuracy * 100))`

In C++ code I am loading the model and trying to make prediction:

   `cppflow::model model("...");
    cv::Mat segment = image(cv::Range(box.first, box.first + 64), cv::Range(box.second, box.second + 64));
    segment.convertTo(segment, CV_32F, 1.0 / 255.0);
    cv::Mat flat = segment.reshape(1, segment.total() * 3);

    std::vector<float> image_data(64 * 64 * 3);
    image_data = segment.isContinuous() ? flat : flat.clone();

    cppflow::tensor input(image_data, { 1, 64, 64, 3 });
    auto output = model(input);

    std::cout << output << std::endl;`

Here I crop image segment and I sad I try to make prediction, but in model::operator() I get already mentioned error.

I guess problem is that operation serving_default_conv2d_2_input should be called. But I don't know how to enable something like that. If that is a problem, is there a way to change input operation like in previous version of this library?

Apologies for bad formatting of LeNet5 class, I just can't make it work.

bytosaur commented 2 years ago

hey there,

you can call specific ins and outs! Take a look at https://github.com/serizba/cppflow/blob/master/examples/multi_input_output/main.cpp :)

dacalalic commented 2 years ago

I hard-coded inputs and outputs in model.h, and it worked. But your answer is correct. Thanks

bytosaur commented 2 years ago

yeah these are the standard names. you could have also added an Input layer upfront or named your layer accordingly...

profPlum commented 2 years ago

Hey I'm getting the same error but I'm getting it inside the example that you linked @bytosaur