0

I am training my dataset using VGG as below. It worked well without zca whitening, but after adding zca, it cause an error called

"computation cannot be performed with standard 32-bit LAPACK"

. As you can see, I tried to train the number of batchsize..etc.. to 1, and even just train with 6 images, but it still din not work. What should I do?

Here is my code.

import os
from keras.applications.vgg16 import VGG16
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential, Model
from keras.layers import Input, Activation, Dropout, Flatten, Dense
from keras.preprocessing.image import ImageDataGenerator
from keras import optimizers
import numpy as np
import time
from PIL import Image 
import csv
import shutil

# 分類するクラス
classes = ['sugi', 'hinoki']
nb_classes = len(classes)

img_width, img_height = 256, 256

# トレーニング用とバリデーション用の画像格納先
train_data_dir = 'dataset/train1'
#validation_data_dir = 'dataset/validation'

# 今回はトレーニング用に200枚、バリデーション用に50枚の画像を用意した。
nb_train_samples = 1998
#nb_validation_samples = 50

batch_size = 32
nb_epoch = 10
gen_tr_batches = 4
folder = './output'
result_dir = 'results'
if not os.path.exists(result_dir):
    os.mkdir(result_dir)
train_imagelist = os.listdir(train_data_dir)

def vgg_model_maker():
    """ VGG16のモデルをFC層以外使用。FC層のみ作成して結合して用意する """

    # VGG16のロード。FC層は不要なので include_top=False
    input_tensor = Input(shape=(img_width, img_height, 3))
    vgg16 = VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor)

    # FC層の作成
    top_model = Sequential()
    top_model.add(Flatten(input_shape=vgg16.output_shape[1:]))
    top_model.add(Dense(256, activation='relu'))
    top_model.add(Dropout(0.5))
    top_model.add(Dense(nb_classes, activation='softmax'))

    # VGG16とFC層を結合してモデルを作成
    model = Model(input=vgg16.input, output=top_model(vgg16.output))

    return model



def image_generator():
    """ ディレクトリ内の画像を読み込んでトレーニングデータとバリデーションデータの作成 """
    gen_train = (ImageDataGenerator(rescale=1.0 / 255.).flow_from_directory(train_data_dir,
                    target_size=(img_width, img_height),
                    #color_mode='rgb',
                    batch_size=batch_size,
                    shuffle=True))

    gen_tr_x = np.vstack(next(gen_train)[0] for _ in range(gen_tr_batches))

    #train_datagen = ImageDataGenerator(
    #    rescale=1.0 / 255,
    #    zoom_range=0.2,
    #    horizontal_flip=True,
    #    zca_whitening = True)


    g = ImageDataGenerator(rescale=1.0 / 255.,
                        zca_whitening=True)
    g.fit(gen_tr_x)

    #validation_datagen = ImageDataGenerator(rescale=1.0 / 255)

    train_generator = g.flow_from_directory(
        train_data_dir,
        classes=classes,
        class_mode='categorical')


    #validation_generator = validation_datagen.flow_from_directory(
       # validation_data_dir,
        #target_size=(img_width, img_height),
        #color_mode='rgb',
        #classes=classes,
        #class_mode='categorical',
        #batch_size=batch_size,
        #shuffle=True)

    return (train_generator)





# Generator for the network's training generator.



# Actual generator for the network's training.


if __name__ == '__main__':
    start = time.time()

    for the_file in os.listdir(folder):
        file_path = os.path.join(folder, the_file)
        try:
            if os.path.isfile(file_path):
                os.unlink(file_path)
        #elif os.path.isdir(file_path): shutil.rmtree(file_path)
        except Exception as e:
            print(e)

    # モデル作成
    vgg_model = vgg_model_maker()

    # 最後のconv層の直前までの層をfreeze
    for layer in vgg_model.layers[:15]:
        layer.trainable = False

    # 多クラス分類を指定
    vgg_model.compile(loss='categorical_crossentropy',
              optimizer=optimizers.SGD(lr=1e-3, momentum=0.9),
              metrics=['accuracy'])

    # 画像のジェネレータ生成
    train_generator =  image_generator()


    # Fine-tuning
    history_callback = vgg_model.fit_generator(
        train_generator,
        samples_per_epoch=nb_train_samples,
        nb_epoch=nb_epoch)
        #validation_data=validation_generator,
        #nb_val_samples=nb_validation_samples)

    loss_history = history_callback.history["loss"]
    accuracy_history = history_callback.history["acc"]
    numpy_loss_history = np.array(loss_history)
    numpy_accuracy_history = np.array(accuracy_history)

    f = open("result.csv","w")
    writer = csv.writer(f)
    writer.writerow(["loss","accuracy"])
    for j in range(len(numpy_loss_history)):
        writer.writerow([numpy_loss_history[j],numpy_accuracy_history[j]])

    vgg_model.save_weights(os.path.join(result_dir, 'finetuning.h5'))

    process_time = (time.time() - start) / 60
    print(u'学習終了。かかった時間は', process_time, u'分です。')
nghia95
  • 13
  • 6

2 Answers2

1

My guess is, it's not a tensorflow issue, but rather a numpy issue, and I guess that because here's what's happening when you try to set the zca parameter to True:

    if self.zca_whitening:
        if self.principal_components is not None:
            flatx = np.reshape(x, (-1, np.prod(x.shape[-3:])))
            whitex = np.dot(flatx, self.principal_components)
            x = np.reshape(whitex, x.shape)

By default, when you install numpy, it tries to find a low level linear algebra library installed on your system, and use that. LAPACK is one of them.

numpy will use its own code if no library is available. So try installing your numpy without any of those libraries as suggested in the docs:

BLAS=None LAPACK=None ATLAS=None python setup.py build

If that still uses the libraries, try the solution given here.

Then, if the above workaround solves your problem, try compiling a 64bit LAPACK and compile your numpy against it.

adrin
  • 4,511
  • 3
  • 34
  • 50
  • Thank you. So how can I install numpy without that kind of library? – nghia95 Apr 03 '18 at 09:35
  • Hey there, I am trying what you said but I dont know where is the source code for numpy in my computer. Once I feel like I almost found it, the command line said: "This is the wrong setup.py file to run " – nghia95 Apr 03 '18 at 10:13
  • you shouldn't try to find the `numpy` source on your computer, you should follow the installation path given in the docs. The hyperlink is in the answer I gave. – adrin Apr 03 '18 at 10:53
  • Yah now that error dissapeared, but there is another error: in g.fit(gen_tr_x) the program raise "Memory error". Is it relevant? – nghia95 Apr 03 '18 at 11:35
  • also this line was mentioned sigma = np.dot(flat_x.T, flat_x) / flat_x.shape[0] – nghia95 Apr 03 '18 at 11:36
  • That means now you're using `numpy`'s implementation, which may take more memory that the `LAPACK`s implementation. Now you should try getting a `numpy` compiled against your custom compiled `LAPACK`, or `BLAS` or whatever. WARNING: it can take you some time to figure out how to do that, but it's worth it. – adrin Apr 03 '18 at 11:59
  • also, if an answer helps you, you can upvote and set as accepted answer for us to be motivate to answer your other questions ;) – adrin Apr 03 '18 at 12:07
  • first try to figure out how to compile one of these libraries (of your choise, lapack, blas, etc) for your system (OS dependent). Then follow the numpy's compilation doc and give appropriate paths and parameters for it to find your recently compiled library. – adrin Apr 03 '18 at 12:19
  • Okay I will try. But 1 question: why we tried to install numpy without LAPACK in the previous time, but now we need to compile it? – nghia95 Apr 03 '18 at 12:22
  • `numpy`s implementation is not efficient at all compared to those other mature libraries. You can test your code with numpy`s implementation, but for large datasets and in production, you definitely need something much heavier than pure numpy. – adrin Apr 03 '18 at 12:23
  • Hey, after two days I still cannot find the way. Could you give me some hints? – nghia95 Apr 05 '18 at 09:18
  • To be honest, I think I havent get what you meant by "find your recenly compiled library". Why I have to find it? – nghia95 Apr 05 '18 at 09:26
  • related: https://stackoverflow.com/questions/23463240/how-to-compile-lapack-so-that-it-can-be-used-correctly-during-installation-of-oc – adrin Apr 05 '18 at 09:29
1

This answers the more general problem observed when using lapack function such as svd on very large matrices.

Instead of:

import numpy as np
from scipy.linalg import svd

a = np.ones((30000,30000))
u,s,v = svd(a) # this fails

Use:

u,s,v = svd(a, lapack_driver='gesvd') # this DOES NOT fail

My official ticket with an example is here: https://github.com/scipy/scipy/issues/10337

seralouk
  • 30,938
  • 9
  • 118
  • 133