[QUESTION] C1_W3_Lab_1 Value Error -- Local Machine + Anaconda/JupyterLab

Hello,

I need some guidance/help to run the notebook on a local system.

I am running into a ValueError message on the Convolutional Neural Network cell of the provided Week 3 Lab 1 notebook. The notebook is ran on a local machine with Anaconda installed - tensorflow version 2.3.0. Initial run has no code changes as is and shows the following error message:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Input In [3], in <cell line: 24>()
     22 # Train the model
     23 print(f'\nMODEL TRAINING:')
---> 24 model.fit(training_images, training_labels, epochs=5)
     26 # Evaluate on the test set
     27 print(f'\nMODEL EVALUATION:')

File C:\anaconda\anaconda3\lib\site-packages\tensorflow\python\keras\engine\training.py:108, in enable_multi_worker.<locals>._method_wrapper(self, *args, **kwargs)
    106 def _method_wrapper(self, *args, **kwargs):
    107   if not self._in_multi_worker_mode():  # pylint: disable=protected-access
--> 108     return method(self, *args, **kwargs)
    110   # Running inside `run_distribute_coordinator` already.
    111   if dc_context.get_current_worker_context():

File C:\anaconda\anaconda3\lib\site-packages\tensorflow\python\keras\engine\training.py:1098, in Model.fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, validation_batch_size, validation_freq, max_queue_size, workers, use_multiprocessing)
   1091 with trace.Trace(
   1092     'TraceContext',
   1093     graph_type='train',
   1094     epoch_num=epoch,
   1095     step_num=step,
   1096     batch_size=batch_size):
   1097   callbacks.on_train_batch_begin(step)
-> 1098   tmp_logs = train_function(iterator)
   1099   if data_handler.should_sync:
   1100     context.async_wait()

File C:\anaconda\anaconda3\lib\site-packages\tensorflow\python\eager\def_function.py:780, in Function.__call__(self, *args, **kwds)
    778 else:
    779   compiler = "nonXla"
--> 780   result = self._call(*args, **kwds)
    782 new_tracing_count = self._get_tracing_count()
    783 without_tracing = (tracing_count == new_tracing_count)

File C:\anaconda\anaconda3\lib\site-packages\tensorflow\python\eager\def_function.py:823, in Function._call(self, *args, **kwds)
    820 try:
    821   # This is the first call of __call__, so we have to initialize.
    822   initializers = []
--> 823   self._initialize(args, kwds, add_initializers_to=initializers)
    824 finally:
    825   # At this point we know that the initialization is complete (or less
    826   # interestingly an exception was raised) so we no longer need a lock.
    827   self._lock.release()

File C:\anaconda\anaconda3\lib\site-packages\tensorflow\python\eager\def_function.py:696, in Function._initialize(self, args, kwds, add_initializers_to)
    693 self._lifted_initializer_graph = lifted_initializer_graph
    694 self._graph_deleter = FunctionDeleter(self._lifted_initializer_graph)
    695 self._concrete_stateful_fn = (
--> 696     self._stateful_fn._get_concrete_function_internal_garbage_collected(  # pylint: disable=protected-access
    697         *args, **kwds))
    699 def invalid_creator_scope(*unused_args, **unused_kwds):
    700   """Disables variable creation."""

File C:\anaconda\anaconda3\lib\site-packages\tensorflow\python\eager\function.py:2855, in Function._get_concrete_function_internal_garbage_collected(self, *args, **kwargs)
   2853   args, kwargs = None, None
   2854 with self._lock:
-> 2855   graph_function, _, _ = self._maybe_define_function(args, kwargs)
   2856 return graph_function

File C:\anaconda\anaconda3\lib\site-packages\tensorflow\python\eager\function.py:3213, in Function._maybe_define_function(self, args, kwargs)
   3210   return self._define_function_with_shape_relaxation(args, kwargs)
   3212 self._function_cache.missed.add(call_context_key)
-> 3213 graph_function = self._create_graph_function(args, kwargs)
   3214 self._function_cache.primary[cache_key] = graph_function
   3215 return graph_function, args, kwargs

File C:\anaconda\anaconda3\lib\site-packages\tensorflow\python\eager\function.py:3065, in Function._create_graph_function(self, args, kwargs, override_flat_arg_shapes)
   3060 missing_arg_names = [
   3061     "%s_%d" % (arg, i) for i, arg in enumerate(missing_arg_names)
   3062 ]
   3063 arg_names = base_arg_names + missing_arg_names
   3064 graph_function = ConcreteFunction(
-> 3065     func_graph_module.func_graph_from_py_func(
   3066         self._name,
   3067         self._python_function,
   3068         args,
   3069         kwargs,
   3070         self.input_signature,
   3071         autograph=self._autograph,
   3072         autograph_options=self._autograph_options,
   3073         arg_names=arg_names,
   3074         override_flat_arg_shapes=override_flat_arg_shapes,
   3075         capture_by_value=self._capture_by_value),
   3076     self._function_attributes,
   3077     function_spec=self.function_spec,
   3078     # Tell the ConcreteFunction to clean up its graph once it goes out of
   3079     # scope. This is not the default behavior since it gets used in some
   3080     # places (like Keras) where the FuncGraph lives longer than the
   3081     # ConcreteFunction.
   3082     shared_func_graph=False)
   3083 return graph_function

File C:\anaconda\anaconda3\lib\site-packages\tensorflow\python\framework\func_graph.py:986, in func_graph_from_py_func(name, python_func, args, kwargs, signature, func_graph, autograph, autograph_options, add_control_dependencies, arg_names, op_return_value, collections, capture_by_value, override_flat_arg_shapes)
    983 else:
    984   _, original_func = tf_decorator.unwrap(python_func)
--> 986 func_outputs = python_func(*func_args, **func_kwargs)
    988 # invariant: `func_outputs` contains only Tensors, CompositeTensors,
    989 # TensorArrays and `None`s.
    990 func_outputs = nest.map_structure(convert, func_outputs,
    991                                   expand_composites=True)

File C:\anaconda\anaconda3\lib\site-packages\tensorflow\python\eager\def_function.py:600, in Function._defun_with_scope.<locals>.wrapped_fn(*args, **kwds)
    585 # We register a variable creator with reduced priority. If an outer
    586 # variable creator is just modifying keyword arguments to the variable
    587 # constructor, this will work harmoniously. Since the `scope` registered
   (...)
    595 # better than the alternative, tracing the initialization graph but giving
    596 # the user a variable type they didn't want.
    597 with ops.get_default_graph()._variable_creator_scope(scope, priority=50):  # pylint: disable=protected-access
    598   # __wrapped__ allows AutoGraph to swap in a converted function. We give
    599   # the function a weak reference to itself to avoid a reference cycle.
--> 600   return weak_wrapped_fn().__wrapped__(*args, **kwds)

File C:\anaconda\anaconda3\lib\site-packages\tensorflow\python\framework\func_graph.py:973, in func_graph_from_py_func.<locals>.wrapper(*args, **kwargs)
    971 except Exception as e:  # pylint:disable=broad-except
    972   if hasattr(e, "ag_error_metadata"):
--> 973     raise e.ag_error_metadata.to_exception(e)
    974   else:
    975     raise

ValueError: in user code:

    C:\anaconda\anaconda3\lib\site-packages\tensorflow\python\keras\engine\training.py:806 train_function  *
        return step_function(self, iterator)
    C:\anaconda\anaconda3\lib\site-packages\tensorflow\python\keras\engine\training.py:796 step_function  **
        outputs = model.distribute_strategy.run(run_step, args=(data,))
    C:\anaconda\anaconda3\lib\site-packages\tensorflow\python\distribute\distribute_lib.py:1211 run
        return self._extended.call_for_each_replica(fn, args=args, kwargs=kwargs)
    C:\anaconda\anaconda3\lib\site-packages\tensorflow\python\distribute\distribute_lib.py:2585 call_for_each_replica
        return self._call_for_each_replica(fn, args, kwargs)
    C:\anaconda\anaconda3\lib\site-packages\tensorflow\python\distribute\distribute_lib.py:2945 _call_for_each_replica
        return fn(*args, **kwargs)
    C:\anaconda\anaconda3\lib\site-packages\tensorflow\python\keras\engine\training.py:789 run_step  **
        outputs = model.train_step(data)
    C:\anaconda\anaconda3\lib\site-packages\tensorflow\python\keras\engine\training.py:747 train_step
        y_pred = self(x, training=True)
    C:\anaconda\anaconda3\lib\site-packages\tensorflow\python\keras\engine\base_layer.py:975 __call__
        input_spec.assert_input_compatibility(self.input_spec, inputs,
    C:\anaconda\anaconda3\lib\site-packages\tensorflow\python\keras\engine\input_spec.py:191 assert_input_compatibility
        raise ValueError('Input ' + str(input_index) + ' of layer ' +

    ValueError: Input 0 of layer sequential_1 is incompatible with the layer: : expected min_ndim=4, found ndim=3. Full shape received: [32, 28, 28]

Does the error indicate that the training_images shape needs to be different from 60000x28x28 … even though it was explicitly asked to see the images as 28x28x1 on the Conv2D line via the Convolutional Neural Network cell?

Adding the following code (below) gets me to run the cell further but still fails after the 5 epoch on sequential_1 or when sequential_2 begins, which still provides the same ValueError message.

training_images = training_images.reshape(-1, 28, 28, 1)

Thank you.

For the first Conv2D layer, input_shape should be set to (height, width, channels)
training_images should be of form (num images, height, width, channels)

Hope this helps to sort the issue sir