error while finetuning for Regression task.
Author: SAIVENKATARAJU
Pull request: no
Labels: name: wontfix

Hi I was trying to perform finetuning regression task . below is my network.

```
from transformers import TFBertForSequenceClassification
# model initialization
base_model = TFBertForSequenceClassification.from_pretrained('bert-base-uncased')
base_model.bert.trainable=False
model=tf.keras.Sequential(base_model)
model.add(tf.keras.Input(shape=[720895,7],name='Input_1'))
model.add(tf.keras.layers.Dense(1,activation='linear'))
optimizer = tf.keras.optimizers.RMSprop(learning_rate=1e-4)

model.compile(loss='mse',
                  optimizer=optimizer,
                  metrics=['mae', 'mse'])
model.fit(train_seq,train_labels,epochs=10)
```
error is 

`
    TypeError: Failed to convert 'TFSequenceClassifierOutput(loss=None, logits=TensorShape([None, 2]), hidden_states=None, attentions=None)' to a shape: ''logits''could not be converted to a dimension. A shape should either be single dimension (e.g. 10), or an iterable of dimensions (e.g. [1, 10, None]).`


Can you please help me with this.

Comments:
This issue has been automatically marked as stale and been closed because it has not had recent activity. Thank you for your contributions.

If you think this still needs to be addressed please comment on this thread.

Was this solved somehow?


Ping @Rocketknight1 

Hi, the problem here is that our models have more than one output, and therefore don't work that well inside `Sequential`. You can do this with the [Keras functional API](https://keras.io/guides/functional_api/), or by [overriding `train_step`](https://keras.io/guides/customizing_what_happens_in_fit/) or just writing eager TF code.

However, you might not need to do any of that, as our `SequenceClassification` models actually already support regression! If you set `num_labels=1`, we assume you want to do regression instead. So then the above code would just become:

```
from transformers import TFBertForSequenceClassification
model = TFBertForSequenceClassification.from_pretrained('bert-base-uncased', num_labels=1)
optimizer = tf.keras.optimizers.RMSprop(learning_rate=1e-4)

model.compile(loss='mse',
                  optimizer=optimizer,
                  metrics=['mae', 'mse'])
model.fit(train_seq,train_labels,epochs=10)
```

You could also try replacing the optimizer with `tf.keras.optimizers.Adam(learning_rate=2e-5)`, as we find Adam usually works a bit better than RMSprop in practice on Transformer models.

Hi @Rocketknight1 
I was preforming a classification task. The code is
`model = TFAutoModelForSequenceClassification.from_pretrained("bert-base-cased", num_labels=TOTAL_LABELS)
for layer in model.layers:
    layer.trainable= True

for layer in model.layers[:int(len(model.layers)*0.9) ]:
    layer.trainable= False`

Saved the model as 
`tf.keras.models.save_model(model, PATH, overwrite=True, include_optimizer=True, save_format="tf")`

And then got an error while loading
`model= tf.keras.models.load_model(PATH)`

Also can you please provide a link to the docs to set configs to mute the multiple outputs and get only logits as output from a BERT in tensorflow so that I can build a functional API and build layers on top of BERT. Thank you!

> Hi, the problem here is that our models have more than one output, and therefore don't work that well inside `Sequential`. You can do this with the [Keras functional API](https://keras.io/guides/functional_api/), or by [overriding `train_step`](https://keras.io/guides/customizing_what_happens_in_fit/) or just writing eager TF code.
> 
> However, you might not need to do any of that, as our `SequenceClassification` models actually already support regression! If you set `num_labels=1`, we assume you want to do regression instead. So then the above code would just become:
> 
> ```
> from transformers import TFBertForSequenceClassification
> model = TFBertForSequenceClassification.from_pretrained('bert-base-uncased', num_labels=1)
> optimizer = tf.keras.optimizers.RMSprop(learning_rate=1e-4)
> 
> model.compile(loss='mse',
>                   optimizer=optimizer,
>                   metrics=['mae', 'mse'])
> model.fit(train_seq,train_labels,epochs=10)
> ```
> 
> You could also try replacing the optimizer with `tf.keras.optimizers.Adam(learning_rate=2e-5)`, as we find Adam usually works a bit better than RMSprop in practice on Transformer models.

I'm trying something very similar to this and getting:

> ValueError: Failed to find data adapter that can handle input: <class 'transformers.tokenization_utils_base.BatchEncoding'>, (<class 'list'> containing values of types {"<class 'float'>"}

Here is the code:

```
import tensorflow as tf
from transformers import TFAutoModelForSequenceClassification, AutoTokenizer, pipeline
from sklearn.model_selection import train_test_split

model_name = "bert-base-cased"
model = TFAutoModelForSequenceClassification.from_pretrained(model_name, num_labels=1)
model.compile(optimizer="adam", loss="mse")

tokenizer = AutoTokenizer.from_pretrained(model_name)

max_length = 64
X_train, X_test, y_train, y_test = train_test_split(df["Clean"].tolist(), df["Y"].tolist(), test_size=0.2)
train_encodings = tokenizer(X_train, truncation=True, padding=True, max_length=max_length)
valid_encodings = tokenizer(X_test, truncation=True, padding=True, max_length=max_length)

model.fit(train_encodings, y_train, epochs=3)
```

Any suggestions?

Hi @jhogg11 - the error happens because our tokenizers output `BatchEncoding` objects, not dicts, and Keras doesn't know what to do with them! It's also good practice to convert your labels to an array rather than passing them as a list. Try the following right before `model.fit()`:

```
X_train = dict(X_train)
y_train = np.array(y_train)
```

> Hi @jhogg11 - the error happens because our tokenizers output `BatchEncoding` objects, not dicts, and Keras doesn't know what to do with them! It's also good practice to convert your labels to an array rather than passing them as a list. Try the following right before `model.fit()`:
> 
> ```
> X_train = dict(X_train)
> y_train = np.array(y_train)
> ```

Trying `X_train = dict(X_train)` gives me this error (since X_train is a list):

> ValueError: dictionary update sequence element #0 has length 117; 2 is required

I thought you might have meant `dict(train_encodings)` so I tried that, but it gives a similar error as the previous example.

Ah, I'm sorry, you're right! I meant to type `train_encodings`. And now you mention it, I realize the problem is actually twofold. Try replacing this:

```
max_length = 64
X_train, X_test, y_train, y_test = train_test_split(df["Clean"].tolist(), df["Y"].tolist(), test_size=0.2)
train_encodings = tokenizer(X_train, truncation=True, padding=True, max_length=max_length)
valid_encodings = tokenizer(X_test, truncation=True, padding=True, max_length=max_length)
```

with this:

```
max_length = 64
X_train, X_test, y_train, y_test = train_test_split(df["Clean"].tolist(), df["Y"].tolist(), test_size=0.2)
train_encodings = tokenizer(X_train, truncation=True, padding=True, max_length=max_length, return_tensors="np")
valid_encodings = tokenizer(X_test, truncation=True, padding=True, max_length=max_length, return_tensors="np")

train_encodings = dict(train_encodings)
valid_encodings = dict(valid_encodings)

```

The cause of the problem is two things - firstly the `BatchEncoding` output by the tokenizer needs to be converted to a `dict`, and secondly the individual arrays output by the tokenizer need to be converted to an array format (either NumPy or TF) that Keras can understand. The `return_tensors` argument to the tokenizer will take care of that part.

Still not working.  Here's the full code as of now:

EDIT: updated this to be fully reproducible by pulling some random online text data into a dataframe.

```
import pandas as pd
import numpy as np

import tensorflow as tf
from transformers import TFAutoModelForSequenceClassification, AutoTokenizer, pipeline
from sklearn.model_selection import train_test_split

import requests

data = requests.get("https://example-files.online-convert.com/document/txt/example.txt")
data = [d for d in data.text.split("\n") if d != ""]

df = pd.DataFrame(data, columns=["Clean"])
df["Y"] = np.random.normal(0,1, df.shape[0])


model_name = "bert-base-cased"
model = TFAutoModelForSequenceClassification.from_pretrained(model_name, num_labels=1)
# loss = tf.losses.SparseCategoricalCrossentropy(from_logits=True)
model.compile(optimizer="adam", loss="mse")

tokenizer = AutoTokenizer.from_pretrained(model_name)

max_length = 64
X_train, X_test, y_train, y_test = train_test_split(df["Clean"].tolist(), df["Y"].tolist(), test_size=0.2)
train_encodings = tokenizer(X_train, truncation=True, padding=True, max_length=max_length, return_tensors="np")
valid_encodings = tokenizer(X_test, truncation=True, padding=True, max_length=max_length, return_tensors="np")

train_encodings = dict(train_encodings)
valid_encodings = dict(valid_encodings)

model.fit(
    train_encodings,
    y_train,
    epochs=3,
)
```


The error message is:

```
ValueError: Failed to find data adapter that can handle input: (<class 'dict'> containing {"<class 'str'>"} keys and {"<class 'numpy.ndarray'>"} values), (<class 'list'> containing values of types {"<class 'float'>"})
```
I had also looked at: https://huggingface.co/docs/transformers/v4.27.2/en/quicktour#train-with-tensorflow and https://huggingface.co/docs/transformers/v4.27.2/en/training#prepare-a-dataset, but all of the examples that I could find involve preloaded datasets.

Is there a way to efficiently go from a dataframe or list to a `Dataset` object?

@jhogg11 Thanks for sharing a fully reproducible example. I believe the issue is still arising as `y_train` being passed to the model is a list. Running the following should work: 

```py
model.fit(train_encodings, tf.convert_to_tensor(y_train), epochs=3)
```

@amyeroberts

Getting basically the same error:
```
ValueError: Failed to find data adapter that can handle input: <class 'tensorflow.python.framework.ops.EagerTensor'>, (<class 'list'> containing values of types {"<class 'float'>"})
````
Does the code work for you?  I recently had to re-install Miniconda and I'm also on an M1 Mac, which can create difficulties, so I'm wondering if it's something on my end.  However, I did test a basic TF model (using random numbers) just to make sure that everything is working and it trained without issue.

@jhogg11 Yes, it works for me. When I run: 
```py
import pandas as pd
import numpy as np

import tensorflow as tf
from transformers import TFAutoModelForSequenceClassification, AutoTokenizer, pipeline
from sklearn.model_selection import train_test_split
import requests

data = requests.get("https://example-files.online-convert.com/document/txt/example.txt")
data = [d for d in data.text.split("\n") if d != ""]

df = pd.DataFrame(data, columns=["Clean"])
df["Y"] = np.random.normal(0,1, df.shape[0])

model_name = "bert-base-cased"
model = TFAutoModelForSequenceClassification.from_pretrained(model_name, num_labels=1)
# loss = tf.losses.SparseCategoricalCrossentropy(from_logits=True)
model.compile(optimizer="adam", loss="mse")

tokenizer = AutoTokenizer.from_pretrained(model_name)

max_length = 64
X_train, X_test, y_train, y_test = train_test_split(df["Clean"].tolist(), df["Y"].tolist(), test_size=0.2)
train_encodings = tokenizer(X_train, truncation=True, padding=True, max_length=max_length, return_tensors="np")
valid_encodings = tokenizer(X_test, truncation=True, padding=True, max_length=max_length, return_tensors="np")

train_encodings = dict(train_encodings)
valid_encodings = dict(valid_encodings)

model.fit(train_encodings, tf.convert_to_tensor(y_train), epochs=3)
```

This was running on an M1 with 
```
transformers                  4.28.0.dev0
tensorflow-macos              2.10.0
tensorflow-metal              0.6.0
````

Which versions of transformers and tensorflow are you using? 

@amyeroberts

I just restarted the kernel and ran with your exact code and it worked!  I think I might have hastily wrapped `train_encodings` in `tf.convert_to_tensor` rather than `y_train`.

I really appreciate the help.