{"action":"created","issue":{"url":"https://api.github.com/repos/BVLC/caffe/issues/462","labels_url":"https://api.github.com/repos/BVLC/caffe/issues/462/labels{/name}","comments_url":"https://api.github.com/repos/BVLC/caffe/issues/462/comments","events_url":"https://api.github.com/repos/BVLC/caffe/issues/462/events","html_url":"https://github.com/BVLC/caffe/issues/462","id":34477370,"number":462,"title":"How to classify 1-channel inputs with the python wrapper (LeNet deploy)","user":{"login":"pjstimac","id":7724464,"avatar_url":"https://avatars.githubusercontent.com/u/7724464?v=3","gravatar_id":"","url":"https://api.github.com/users/pjstimac","html_url":"https://github.com/pjstimac","followers_url":"https://api.github.com/users/pjstimac/followers","following_url":"https://api.github.com/users/pjstimac/following{/other_user}","gists_url":"https://api.github.com/users/pjstimac/gists{/gist_id}","starred_url":"https://api.github.com/users/pjstimac/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pjstimac/subscriptions","organizations_url":"https://api.github.com/users/pjstimac/orgs","repos_url":"https://api.github.com/users/pjstimac/repos","events_url":"https://api.github.com/users/pjstimac/events{/privacy}","received_events_url":"https://api.github.com/users/pjstimac/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/BVLC/caffe/labels/question","name":"question","color":"a806aa"}],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":24,"created_at":"2014-05-28T15:28:15Z","updated_at":"2015-03-04T00:08:24Z","closed_at":"2014-05-28T17:54:56Z","body":"Greetings,\r\n\r\nI'm evaluating Caffe for a commercial application. I have compiled Caffe and pycaffe and matcaffe and everything appears to be good: the installation passed all tests that are run using make runtest. \r\n\r\nNow I want to use the python wrapper to do a simple image classification. I am trying to use a trained mnist network to do the classification (staying away from the imagenet example due to the commercial restriction associated with obtaining the pretrained network).\r\n\r\nFor my lenet_deploy.prototxt I changed the very beginning and end of the example lenet_test.prototxt. In the beginning of lenet_deploy.prototxt I have the following before the first convolutional layer for my non-RGB single test image of size [28,28]:\r\n\r\nname: \"LeNet-deploy\"\r\ninput: \"data\"\r\ninput_dim: 1\r\ninput_dim: 1\r\ninput_dim: 28\r\ninput_dim: 28\r\n\r\nAt the end of lenet_deploy.prototxt I have:\r\n\r\nlayers {\r\n  name: \"prob\"\r\n  type: SOFTMAX\r\n  bottom: \"ip2\"\r\n  top: \"prob\"\r\n}\r\n\r\nFor the trained model I simply used the lenet_iter_10000 result, which seems very good, and renamed it to lenet_pretrained. Now I want to classify my non-RGB image of size [28 28] by running the python wrapper with the options listed below:\r\n\r\npython classify.py \r\n--model_def='/usr/local/caffe/examples/mnist/lenet_deploy.prototxt' --pretrained_model='/usr/local/caffe/examples/mnist/lenet_pretrained' \r\n--gpu \r\n--center_only \r\n--images_dim='28,28' \r\n--mean_file='' \r\n/usr/local/caffe/examples/images/cat2.jpg \r\n/usr/local/caffe/examples/mnist/looker\r\n\r\nLaunching the python script results in the network being read in, but it fails in pycaffe.py line 66 in _Net_forward:\r\n\r\nself.blobs[in_].data[...] = blob\r\nValueError: could not broadcast input array from shape (1,3,28,28) into shape (1,1,28,28)\r\n\r\nI interpret this error to mean that the code (or the pretrained network?) is expecting a 3 channel image (RGB or the like), but it is only seeing a single channel image. If that is the right interpretation how do I change this? I've spent a lot of time looking at the various posts on this site, but I haven't been able to get past this point. My apologies if I'm missing something super obvious here.\r\n\r\nMany thanks for your time.\r\n\r\n\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/BVLC/caffe/issues/comments/77068520","html_url":"https://github.com/BVLC/caffe/issues/462#issuecomment-77068520","issue_url":"https://api.github.com/repos/BVLC/caffe/issues/462","id":77068520,"user":{"login":"wang4249","id":8638700,"avatar_url":"https://avatars.githubusercontent.com/u/8638700?v=3","gravatar_id":"","url":"https://api.github.com/users/wang4249","html_url":"https://github.com/wang4249","followers_url":"https://api.github.com/users/wang4249/followers","following_url":"https://api.github.com/users/wang4249/following{/other_user}","gists_url":"https://api.github.com/users/wang4249/gists{/gist_id}","starred_url":"https://api.github.com/users/wang4249/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wang4249/subscriptions","organizations_url":"https://api.github.com/users/wang4249/orgs","repos_url":"https://api.github.com/users/wang4249/repos","events_url":"https://api.github.com/users/wang4249/events{/privacy}","received_events_url":"https://api.github.com/users/wang4249/received_events","type":"User","site_admin":false},"created_at":"2015-03-04T00:08:24Z","updated_at":"2015-03-04T00:08:24Z","body":"```\r\n#!/usr/bin/env python\r\n\"\"\"\r\nclassify.py is an out-of-the-box image classifer callable from the command line.\r\nBy default it configures and runs the Caffe reference ImageNet model.\r\n\"\"\"\r\nimport numpy as np\r\nimport pandas as pd\r\nimport os\r\nimport sys\r\nimport argparse\r\nimport glob\r\nimport time\r\nfrom skimage.color import rgb2gray\r\nimport caffe\r\n\r\n\r\ndef main(argv):\r\n    pycaffe_dir = os.path.dirname(__file__)\r\n\r\n    parser = argparse.ArgumentParser()\r\n    # Required arguments: input and output files.\r\n    parser.add_argument(\r\n        \"input_file\",\r\n        help=\"Input image, directory, or npy.\"\r\n    )\r\n    parser.add_argument(\r\n        \"output_file\",\r\n        help=\"Output npy filename.\"\r\n    )\r\n    # Optional arguments.\r\n    parser.add_argument(\r\n        \"--model_def\",\r\n        default=os.path.join(pycaffe_dir,\r\n                \"../models/bvlc_reference_caffenet/deploy.prototxt\"),\r\n        help=\"Model definition file.\"\r\n    )\r\n    parser.add_argument(\r\n        \"--pretrained_model\",\r\n        default=os.path.join(pycaffe_dir,\r\n                \"../models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel\"),\r\n        help=\"Trained model weights file.\"\r\n    )\r\n    parser.add_argument(\r\n        \"--gpu\",\r\n        action='store_true',\r\n        help=\"Switch for gpu computation.\"\r\n    )\r\n    parser.add_argument(\r\n        \"--center_only\",\r\n        action='store_true',\r\n        help=\"Switch for prediction from center crop alone instead of \" +\r\n             \"averaging predictions across crops (default).\"\r\n    )\r\n    parser.add_argument(\r\n        \"--images_dim\",\r\n        default='256,256',\r\n        help=\"Canonical 'height,width' dimensions of input images.\"\r\n    )\r\n    parser.add_argument(\r\n        \"--mean_file\",\r\n        default=os.path.join(pycaffe_dir,\r\n                             'caffe/imagenet/ilsvrc_2012_mean.npy'),\r\n        help=\"Data set image mean of [Channels x Height x Width] dimensions \" +\r\n             \"(numpy array). Set to '' for no mean subtraction.\"\r\n    )\r\n    parser.add_argument(\r\n        \"--input_scale\",\r\n        type=float,\r\n        help=\"Multiply input features by this scale to finish preprocessing.\"\r\n    )\r\n    parser.add_argument(\r\n        \"--raw_scale\",\r\n        type=float,\r\n        default=255.0,\r\n        help=\"Multiply raw input by this scale before preprocessing.\"\r\n    )\r\n    parser.add_argument(\r\n        \"--channel_swap\",\r\n        default='2,1,0',\r\n        help=\"Order to permute input channels. The default converts \" +\r\n             \"RGB -> BGR since BGR is the Caffe default by way of OpenCV.\"\r\n    )\r\n    parser.add_argument(\r\n        \"--ext\",\r\n        default='jpg',\r\n        help=\"Image file extension to take as input when a directory \" +\r\n             \"is given as the input file.\"\r\n    )\r\n    parser.add_argument(\r\n        \"--labels_file\",\r\n        default=os.path.join(pycaffe_dir,\r\n                \"../data/ilsvrc12/synset_words.txt\"),\r\n        help=\"Readable label definition file.\"\r\n    )\r\n\r\n    parser.add_argument(\r\n        \"--print_results\",\r\n        action='store_true',\r\n        help=\"Write output text to stdout rather than serializing to a file.\"\r\n    )\r\n\r\n    parser.add_argument(\r\n        \"--force_grayscale\",\r\n        action='store_true',\r\n        help=\"Converts RGB images down to single-channel grayscale versions,\" +\r\n             \"useful for single-channel networks like MNIST.\"\r\n    )\r\n\r\n    args = parser.parse_args()\r\n\r\n    image_dims = [int(s) for s in args.images_dim.split(',')]\r\n\r\n    mean, channel_swap = None, None\r\n    if args.force_grayscale:\r\n        channels_swap = None\r\n        mean_file = None\r\n    else:\r\n        mean = np.load(args.mean_file).mean(1).mean(1)\r\n        channel_swap = [int(s) for s in args.channel_swap.split(',')]\r\n\r\n    # Make classifier.\r\n    classifier = caffe.Classifier(args.model_def, args.pretrained_model,\r\n            image_dims=image_dims, mean=mean,\r\n            input_scale=args.input_scale, raw_scale=args.raw_scale,\r\n            channel_swap=channel_swap)\r\n\r\n    if args.gpu:\r\n        caffe.set_mode_gpu()\r\n        print('GPU mode')\r\n\r\n    # Load numpy array (.npy), directory glob (*.jpg), or image file.\r\n    args.input_file = os.path.expanduser(args.input_file)\r\n    if args.input_file.endswith('npy'):\r\n        inputs = np.load(args.input_file)\r\n    elif os.path.isdir(args.input_file):\r\n        inputs =[caffe.io.load_image(im_f)\r\n                 for im_f in glob.glob(args.input_file + '/*.' + args.ext)]\r\n    else:\r\n        inputs = [caffe.io.load_image(args.input_file)]\r\n\r\n    # if args.force_grayscale:\r\n    #   inputs = [rgb2gray(input) for input in inputs];\r\n\r\n\r\n    print(\"Classifying %d inputs.\" % len(inputs))\r\n\r\n    # Classify.\r\n    start = time.time()\r\n    scores = classifier.predict(inputs, not args.center_only).flatten()\r\n    print(\"Done in %.2f s.\" % (time.time() - start))\r\n\r\n    if args.print_results:\r\n        with open(args.labels_file) as f:\r\n          labels_df = pd.DataFrame([\r\n               {\r\n                   'synset_id': l.strip().split(' ')[0],\r\n                   'name': ' '.join(l.strip().split(' ')[1:]).split(',')[0]\r\n               }\r\n               for l in f.readlines()\r\n            ])\r\n        labels = labels_df.sort('synset_id')['name'].values\r\n\r\n        indices = (-scores).argsort()[:5]\r\n        predictions = labels[indices]\r\n\r\n        meta = [\r\n                   (p, '%.5f' % scores[i])\r\n                   for i, p in zip(indices, predictions)\r\n               ]\r\n\r\n        print meta\r\n\r\n\r\n\r\n    # Save\r\n    np.save(args.output_file, predictions)\r\n\r\n\r\nif __name__ == '__main__':\r\n    main(sys.argv)\r\n```\r\n"}}